创建依赖类时,JavaCompiler 给出错误

标签 java javacompiler

我编写了一个生成两个类的代码,我将它们写入缓冲区并使用 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/

相关文章:

java - Postgres Hibernate 设置 session 变量以实现行级安全性

java - Spark java : how to handle multipart/form-data input?

java - 文件以错误的编码加载 : 'UTF-8' in android studio

JavaCompiler编译的类找不到

android - 错误 : when I replace compile with implementation in gradle(dependency)

java - 是否有网站可以远程上传mysql数据库并连接Java Swing应用程序

java - 如何读取在 apache tomcat 中运行的 webapp 的 list 文件?

java - 无论如何告诉编译器通过注释保留变量名?

java - Java 8 中 try-with-resources block 中的锁风险