如何使用 Java 编译器 API 递归编译 Java 文件



我最近在研究Java编译器API,我编写了一些代码,可以将一个简单的java源代码文件编译为类文件,但它不能编译引用其他源代码文件中另一个类的源代码文件。下面是我的代码:

public static void main(String[] args) throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        Path path = Paths.get("demo/Test2.java");
        File sourceFile = path.toFile();
        // set compiler's classpath to be same as the runtime's
        String classpath = System.getProperty("java.class.path");
        optionList.addAll(Arrays.asList("-classpath", classpath));
        optionList = Arrays.asList("-d", "demo_class");
        try (StandardJavaFileManager fileManager =
                compiler.getStandardFileManager(null, null, null)) {
            Iterable<? extends JavaFileObject> fileObjects =
                    fileManager.getJavaFileObjects(sourceFile);
            JavaCompiler.CompilationTask task =
                    compiler.getTask(null, null, null, options, null, fileObjects);
            Boolean result = task.call();
            if (result == null || !result.booleanValue()) {
                throw new RuntimeException(
                        "Compilation failed. class file path:" + sourceFile.getPath());
            }
        }
    }

演示/测试.java:

public class Test1 {}

演示/测试2.java:

public class Test2 extends Test1{
    public static void main(String[] args) {
        System.out.println("Test2 compiled.");
    }
}

输出:

demo/Test2.java:2: error: cannot find symbol
public class Test2 extends Test1{
                           ^
  symbol: class Test1
1 error
Exception in thread "main" java.lang.RuntimeException: Compilation failed. class file path:demo/Test2.java
    at test.DynamicCompile.main(DynamicCompile.java:28)

我的问题是如何让编译器知道类Test1在文件Test1.java中,并且该文件与Test2.java位于同一源代码文件夹中,以便它可以递归编译?

你应该将这两个类作为输入传递

public static void main(String[] args) throws IOException {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    List<String> sources = Arrays.asList(new String[] {"demo/Test2.java", "demo/Test1.java"});
    // set compiler's classpath to be same as the runtime's
    String classpath = System.getProperty("java.class.path");
    List<String> optionList = new ArrayList<>();
    optionList.addAll(Arrays.asList("-classpath", classpath));
    optionList = Arrays.asList("-d", "demo_class");
    try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) {
        Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjectsFromStrings(sources);
        JavaCompiler.CompilationTask task = compiler.getTask(null, null, null, optionList, null, fileObjects);
        Boolean result = task.call();
        if (result == null || !result) {
            throw new RuntimeException(
                    "Compilation failed. class file path:" + fileObjects);
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}

最新更新