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

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM