首先我尝试实现的目标:
我想在运行时期间在内存中动态编译java类。基本上使用提供的Java编译器API并不是什么大不了的事,但是当涉及每个.java文件的多个类时,我就迷失了。
到目前为止我得到了什么:
我目前正在处理此问题的答案中提供的InMemoryJavaCompiler
(Compile 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)
答案 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
来保存所有类的编译代码。
虽然你很久以前就问过这个问题,但我希望这会有所帮助。