我最近在研究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();
}
}