zoukankan      html  css  js  c++  java
  • Java程序动态编译Java源文件

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

    先贴出官网推荐写法:

    JavaCompiler.CompilationTask getTask(Writer out,
                                         JavaFileManager fileManager,
                                         DiagnosticListener<? super JavaFileObject> diagnosticListener,
                                         Iterable<String> options,
                                         Iterable<String> 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<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    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<File> sourceFiles = new ArrayList<File>();
      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<File> 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<File> 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();

    }

  • 相关阅读:
    [原创]二路归并排序针对数组的场景(C++版)
    [原创]装饰模式(java版)
    [原创]Java中Map根据值(value)进行排序实现
    [原创]适配器模式(java版)
    信了你的邪
    String和Date转换
    电商运营面试题
    springCloud发送请求多对象参数传递问题
    JS实现页面以年月日时分秒展示时间
    java三种注释以及参数涵义(转)
  • 原文地址:https://www.cnblogs.com/xxjcai/p/10881371.html
Copyright © 2011-2022 走看看