• 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();

    }

  • 相关阅读:
    IOS编程之通讯录
    和iPhone有关的视图控制器:UIViewController、UITabBarController、UINavigationController及其混合用法
    跟大家分享下今天所学到的PHP,虽然很基础,但是感觉也很重要
    直接拿来用!最火的iOS开源项目
    ios各种手势,很有意思
    IOS中Json解析的四种方法
    [iOS]深入浅出 iOS 之多线程 NSThread
    IOS应用程序升级
    ios学习笔记之block在ios开发中的应用
    【热门收藏】iOS开发人员必看的精品资料(100个)——下载目录
  • 原文地址:https://www.cnblogs.com/xxjcai/p/10881371.html
Copyright © 2020-2023  润新知