Java程序动态编译Java源文件

最近接触到公司一个项目,需要将生成的源码动态编译,记录下学习过程。

先贴出官网推荐写法:

JavaCompiler.CompilationTask getTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable options,
Iterable classes,
Iterable<? extends JavaFileObject> compilationUnits)

参数:out - 用于来自编译器的其他输出的 Writer;如果为 null,则使用 System.err

fileManager - 文件管理器;如果为 null,则使用编译器的标准文件管理器

标准文件管理器有两个用途:

• 自定义编译器如何读写文件的基本构建块

• 在多个编译任务之间共享

diagnosticListener - 诊断侦听器;如果为 null,则使用编译器的默认方法报告诊断信息

options - 编译器选项; null 表示没有选项

classes - 类名称(用于注释处理), null 表示没有类名称

compilationUnits - 要编译的编译单元; null 表示没有编译单元

Files[] files1 = …; // input for first compilation task
Files[] files2 = …; // input for second compilation task

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

//DiagnosticCollector为诊断侦听器,用于将诊断信息收集在一个列表中

//可以不设置,为null时默认使用system.err

DiagnosticCollector diagnostics = new DiagnosticCollector();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
//自定义编译器读写文件的基本构件块
Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(files1));
compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits1).call();

Iterable<? extends JavaFileObject> compilationUnits2 = fileManager.getJavaFileObjects(files2); // use alternative method
// reuse the same file manager to allow caching of jar files
compiler.getTask(null, fileManager, null, null, null, compilationUnits2).call();

for (Diagnostic diagnostic :diagnostics.getDiagnostics())
System.out.format(“Error on line %d in %d%n”,
diagnostic.getLineNumber()
diagnostic.getSource().toUri());

fileManager.close();

记录下自己的一段代码:

public static void main(String[] args) {

//class文件生成目录
String targetPath=“D:\generate\target”;

//源文件目录
String sourcePath=“D:\generate\source”;
File sourceFile=new File(sourcePath);
List sourceFiles = new ArrayList();
compiler(sourceFile,targetPath,sourceFiles);
boolean result = compilerJavaFile(sourceFiles, targetPath);
System.out.println(“compiler finish!” + result);
}

/**

  • 递归获取java文件
  • @param file 需要编译的文件夹
  • @param targetPath 编译后class类文件存放目录
    */
    public static void compiler(File file,String targetPath,List sourceFiles) {
    File targetDir = new File(targetPath);
    if (! targetDir.exists())
    {
    targetDir.mkdirs();
    }
    if (file != null && file.exists()){
      File[] listFiles = file.listFiles();
      if (null == listFiles || listFiles.length == 0) {
        return;
      }
      for (File file2 : listFiles) {
         // 判断是否是文件夹
        if (file2.isDirectory()) {
          compiler(file2,targetPath,sourceFiles);
        } else {
        if (file2.getName().endsWith(".java")) {
         //将源文件目录中的Java文件加入集合中
        sourceFiles.add(file2);
        }
      }
     }
    }else{
      System.out.println(“传入格式未知文件”);
    }
    }

/**

  • 编译java文件
  • @param sourcePath
  • @param targerPath
  • @return
    */
    public static boolean compilerJavaFile(List sourceFile, String targerPath) {

StandardJavaFileManager fileManager = getJavaCompiler().getStandardFileManager(null, null, null);
  Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(sourceFile);
  return getJavaCompiler().getTask(null, fileManager, null, options, null, compilationUnits).call();

}

原文:https://www.cnblogs.com/xxjcai/archive/2019/05/17/10881371.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值