如何从 Java 5 和 Java 6 中的任意字符串(在内存中)编译 Java 代码,加载它并在其上运行特定方法(预定义)?
在你对此进行讨论之前,我查看了现有的实现:
- 大多数依赖于 Java 6 编译器 API。
- 那些不这样做的人,只能依靠技巧。
- 是的,我查看了 commons-jci。要么是我太笨,无法理解它是如何工作的,要么就是不明白。
- 我找不到如何向编译器提供当前的类路径(相当大)。
- 在有效的实现上(在 Java 6 中),我找不到如何正确加载内部类(或内部匿名类)。
- 如果整个东西都在内存中,我会非常喜欢它,因为它可以在多个环境中运行。
我确信这个问题以前已经解决了,但我在谷歌上找不到任何看起来甚至是半生产质量的东西(除了jci,正如我之前所说,我还没有设法使用)。
Edit:
- 我查看了 JavaAssist - 我需要内部类、Java 5.0 语言级别支持并使用整个类路径进行编译。另外,我想动态创建新课程。我
可能是错误的,但我找不到如何使用 JavaAssit 执行此操作。
- 我愿意使用基于文件系统的解决方案(调用 javac),但我不知道如何预测类路径,也不知道如何稍后使用特殊的类加载器加载文件(不在我的类路径中)回收以供多次调用。虽然我确实知道如何研究它,但我更喜欢现成的解决方案。
编辑2:
目前,我对 BeanShell 的“评估”感到满意。显然它做了我需要它做的一切(获取一个字符串,在“当前”类路径的上下文中评估它。它确实错过了一些 Java 5 功能,但它可以使用枚举(不是定义)和编译的“通用”(已删除) )类,所以它应该足以满足我想要的。
I don't want to mark the answer as accepted yet since I do hope for a better solution to come up.
Edit3:接受了 beanshell 的建议 - 它确实效果很好。
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
有什么理由这不应该工作吗?
Edit: added a
MemoryResourceStore
to send the compiled class output to memory, like requested.
另外,设置javac
设置,例如您的情况下的类路径,可以通过setCustomArguments(String[] pCustomArguments) http://commons.apache.org/jci/apidocs/org/apache/commons/jci/compilers/JavacJavaCompilerSettings.html#setCustomArguments(java.lang.String%5B%5D) in JavacJavaCompilerSettings
class.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)