适用于Java 5和Java 6的即时内存Java代码编译

如何从Java 5和Java 6中的任意字符串(在内存中)编译java代码,加载它并在其上运行特定方法(预定义)?

在你点燃之前,我查看了现有的实现:

  • 大多数人依赖Java 6 Compiler API。
  • 那些没有,依靠技巧。
  • 是的,我检查了commons-jci。 要么我太密集了,不能理解它是如何工作的,要么就是它没有。
  • 我找不到如何向编译器提供当前的类路径(这是非常巨大的)。
  • 在有效的实现上(在Java 6中),我找不到如何正确加载内部类(或内部匿名类)。
  • 如果整个东西都在内存中,我会非常喜欢它,因为它在多个环境中运行。

我确信之前已经解决了这个问题,但我找不到任何看起来甚至是谷歌半生产质量的东西(除了jci,正如我之前所说,我还没有设法使用)。

编辑:

  • 我查看了JavaAssist – 我需要内部类,Java 5.0语言级支持以及使用整个类路径进行编译。 另外,我想动态创建新类。 我可能弄错了,但我找不到如何用JavaAssit做到这一点。
  • 我愿意使用基于文件系统的解决方案(调用javac),但我不知道如何划分类路径,也不知道如何使用特殊的类加载器加载文件(不在我的类路径中)回收多次调用。 虽然我知道如何研究它,但我更喜欢现成的解决方案。

Edit2:现在,我满足于BeanShell“评估”。 显然,它完成了我需要它的一切(获取一个字符串,在’当前’类路径的上下文中评估它。它确实错过了一些Java 5特性,但它可以使用枚举(不定义)和编译’generics’(擦除) )类,所以它应该足够我想要的东西。

我不想将答案标记为已被接受,因为我希望能找到更好的解决方案。

Edit3:接受了beanshell建议 – 它确实非常有用。

如果你没有完全依赖编译,可以轻松嵌入像Beanshell,groovy和其他脚本语言这样的解决方案(事实上,java内置了对插入脚本语言的支持,因此你的代码甚至不知道用什么语言脚本写在)

Beanshell应该运行任何100%的java代码IIRC,我相信Groovy可以运行大多数java代码 – 可能全部。

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设置(如您的情况下的类路径)可以通过setCustomArguments(String[] pCustomArguments)类中的setCustomArguments(String[] pCustomArguments)JavacJavaCompilerSettings

您也可以查看Janino。

从他们的网站:

Janino是一个编译器,它读取JavaTM表达式,块,类主体,源文件或一组源文件,并生成直接加载和执行的JavaTM字节码。 Janino不是一个开发工具,而是一个用于运行时编译目的的嵌入式编译器,例如表达式评估程序或JSP之类的“服务器页面”引擎。

http://www.janino.net/

我目前正在一个相当大的任务关键项目中使用它,它工作得很好

Javassist可能会让您感兴趣

在像Tomcat这样的Web容器中运行,首先生成一个JSP页面,然后调用它。

这也允许您通过简单地覆盖JSP页面而不是让您的类加载器慢慢运行来摆脱旧的类定义。

由于速度或不更改代码库而导致的“内存中”要求是什么?

ECJ Eclipse Java编译器

Eclipse提供并使用自己的编译器而不是javac

  • Eclipse编译器在IDE(Eclipse)中使用
  • Eclipse编译器也可以用作Eclipse之外的纯批处理编译器

编译源文件

$ java -jar ecj-3.5.2.jar HelloWorld.java