Java程序动态编译Java源文件

匿名 (未验证) 提交于 2019-12-02 21:35:18

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

先贴出官网推荐写法:

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

文章来源: https://blog.csdn.net/weixin_43641389/article/details/90296596
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!