我编写了一个生成两个类的代码,我将它们写入缓冲区并使用 JavaCompiler 编译它们。我的类在 .java 文件中是这样的;
public class A{
public A() { }
public String toString(){ return "A";}
}
和
public class B extends ArrayList<A> {
public B() {
super();
}
public void addItem(A a)
{
this.add(a);
}
public void print() {
this.print();
}
}
类似这样的东西。
但是,类的名称是随机生成的,当我创建文件时,它会给出这样的错误;
symbol: class A
location: class B
./src/A.java:4:错误:找不到符号
(第4行是“...extends ArrayList...”并且A下面有一个^符号)
我的代码生成器是这样编译的;
首先,我用 A 类型类的模板填充缓冲区,然后像这样编译:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, f.getPath());
之后,我创建另一个缓冲区并用我的 B 类型类模板填充它,然后像这样编译;
System.out.println(f.getParentFile().getPath());
compiler.run(null, null, null, f.getPath());
f 是;
f = new File(("./src/" + name + ".java"));
如何解决这个问题?
最佳答案
正如评论中提到的,当编译类B
时,编译器需要了解类A
。在下面的示例中,我们将已编译类的输出目录 /tmp/bin/
添加到 optionList
中编译器的类路径。
如果您不需要它们,您可以阻止在文件系统上创建源文件
public class CompileDependent {
public static void main(String[] args) {
String sourceClassA = "public class A {"
+ " public String toString() {"
+ " return \"A\";"
+ " }"
+ "}";
String sourceClassB = "import java.util.ArrayList;"
+ "class B extends ArrayList<A> {"
+ " public void addItem(A a) {"
+ " this.add(a);"
+ " }"
+ "}";
List<JavaFileObject> compilationUnits = new ArrayList<>();
compilationUnits.add(new StringJavaFileObject("A.java", sourceClassA));
compilationUnits.add(new StringJavaFileObject("B.java", sourceClassB));
List<String> optionList = new ArrayList<>();
// classpath from current JVM + binary output directory
optionList.add("-classpath");
optionList.add(System.getProperty("java.class.path") + ":/tmp/bin");
// class output directory
optionList.add("-d");
optionList.add("/tmp/bin");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(
null,
Locale.UK,
Charset.forName("UTF-8")
);
boolean compiled = compiler.getTask(
null,
fileManager,
null,
optionList,
null,
compilationUnits).call();
System.out.println("compiled = " + compiled);
}
private static class StringJavaFileObject extends SimpleJavaFileObject {
final String code;
StringJavaFileObject(String name, String code) {
super(URI.create("string:///" + name), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
}
或者您在文件系统上创建 Java 源文件。与上面的代码类似,但对 compilationUnits
进行了一些小更改。假设文件已存储在给定位置。
List<File> sourceFiles = new ArrayList<>();
sourceFiles.add(new File("/tmp/A.java"));
sourceFiles.add(new File("/tmp/B.java"));
关于创建依赖类时,JavaCompiler 给出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35060992/