如何从Java 5和Java 6中的任意字符串(在内存中)编译java代码,加载它并在其上运行特定方法(预定义)?
在你点燃之前,我查看了现有的实现:
我确信之前已经解决了这个问题,但我找不到任何看起来甚至是谷歌半生产质量的东西(除了jci,正如我之前所说,我还没有设法使用)
编辑:
EDIT2: 现在,我对BeanShell“评估”感到满意。显然它完成了我需要的所有东西(获取一个字符串,在'当前'类路径的上下文中评估它。它确实错过了一些Java 5特性,但它可以使用枚举(不定义)和编译'泛型'(擦除) )类,所以它应该足够我想要的。
我不想将答案标记为已接受,因为我希望找到更好的解决方案。
Edit3:接受了beanshell建议 - 它确实非常有效。
答案 0 :(得分:9)
JCI看起来很好。此代码段应该是您的基础:
JavaCompiler compiler = new JavaCompilerFactory().createCompiler("eclipse");
MemoryResourceReader mrr = new MemoryResourceReader();
mrr.add("resource name string", yourJavaSourceString.getBytes());
MemoryResourceStore mrs = new MemoryResourceStore();
CompilationResult result = compiler.compile(sources, mrr, mrs);
// don't need the result, unless you care for errors/warnings
// the class should have been compiled to your destination dir
这不应该有用吗?
<小时/> 编辑添加了MemoryResourceStore
以将已编译的类输出发送到内存,就像请求一样。
此外,设置javac
设置,例如您的案例中的类路径,可以通过JavacJavaCompilerSettings
课程中的setCustomArguments(String[] pCustomArguments)
来完成。
答案 1 :(得分:6)
您也可以查看Janino。
从他们的网站:
Janino是一个编译器,它读取JavaTM表达式,块,类主体,源文件或一组源文件,并生成直接加载和执行的JavaTM字节码。 Janino不是一个开发工具,而是一个用于运行时编译目的的嵌入式编译器,例如:表达式评估程序或“服务器页面”引擎,如JSP。
我目前正在一个非常大的任务关键项目中使用它,它运行得很好
答案 2 :(得分:3)
如果你没有完全依赖于编译,可以轻松嵌入像Beanshell,groovy和其他脚本语言这样的解决方案(实际上,java内置了对插入脚本语言的支持,因此你的代码甚至都没有知道脚本写的是什么语言)
Beanshell应该运行任何100%的java代码IIRC,我相信Groovy可以运行大多数java代码 - 可能全部。
答案 3 :(得分:1)
Javassist可能会让您感兴趣
答案 4 :(得分:0)
在像Tomcat这样的Web容器中运行,首先生成一个JSP页面,然后调用它。
这也允许您通过简单地覆盖JSP页面而不是让您的类加载器缓慢运行来摆脱旧的类定义。
由于速度或不更改代码库而导致的“内存中”要求是什么?
答案 5 :(得分:0)
Eclipse提供并使用自己的编译器而不是javac
编译源文件
$ java -jar ecj-3.5.2.jar HelloWorld.java