每个文件包含多个类的内存中编译

时间:2015-06-24 09:34:30

标签: java in-memory java-compiler-api

首先我尝试实现的目标:
我想在运行时期间在内存中动态编译java类。基本上使用提供的Java编译器API并不是什么大不了的事,但是当涉及每个.java文件的多个类时,我就迷失了。

到目前为止我得到了什么:
我目前正在处理此问题的答案中提供的InMemoryJavaCompilerCompile code fully in memory with javax.tools.JavaCompiler

如上所述,每个文件的单个类的编译没有问题,但我希望能够编译几乎任何有效的.java文件。

例如,我尝试编译的文件(FileOne.java)如下所示:

package test;
public class FileOne {
    public static void main(String args[]) {
        System.out.println("Hello, World");
    }
}
class Functions {
    public static int test(int x) {
        return -x;
    }
}

当我尝试编译像InMemoryJavaCompiler.compile("test.FileOne", source)这样的文件时,我得到一个Exception,标记覆盖的ClassLoader中的defineClass(...)行:

java.lang.ClassFormatError: Extra bytes at the end of class file test/FileOne

内部类也存在这个问题,但我认为它只是某种命名/调用问题:

java.lang.NoClassDefFoundError: test/FileOne (wrong name: test/FileOne$Functions)

1 个答案:

答案 0 :(得分:0)

是的,你是对的,如果一个类有内部或匿名类,那么github上当前可用的InMemoryJavaCompilation不起作用。我遇到了与您描述的完全相同的问题。

经过长时间的搜索,我发现JSCC非常完整。感谢verhas(github用户名)开发它并使其可用。我用嵌套类测试了JSCC,它运行正常。您可以在Github上找到代码以及如何使用它。

https://github.com/verhas/jscc

据我所知,InMemoryJavaCompilation的问题是每个类存储一个byte array。但是,编译器为具有嵌套类或匿名类的类生成多个类。在这种情况下,InMemoryJavaCompilation仅存储编译器返回的最后一个类,并且可能不是顶级类。因此,您可能会获得java.lang.NoClassDefFoundError。 JSCC维护一个Byte Array Map来保存所有类的编译代码。

虽然你很久以前就问过这个问题,但我希望这会有所帮助。