如何在运行时编译和部署一个java类?
我正在编写一个规则引擎,执行由条件结构决定的简单赋值。 规则是XML格式是项目的先决条件。 我已经将我的XML模式build模为简单的代码块。 我希望parsingXML,然后将其转换为Java代码。 然后我希望在运行时编译(并运行)这些代码。 这样做意味着我的规则引擎不再作为解释器,而是执行本地Java字节码。
我已经想出了parsing阶段,或多或less的Java代码生成阶段。 我现在想弄清楚最后一个阶段 – 在运行阶段编译。
遵循这个线程: 编译为java字节码(不使用Java)我已经意识到以下可能的解决scheme:
- ASM
- BCEL
- 特罗韦
我喜欢这些的比较以及其他在运行时阶段解决Java编译的build议。
使用Java 6编译器API 。
你可以把它转换成Clojure代码,Clojure编译器会把它变成你的字节码。
这里是java编译工具,你可以在运行时编译你的代码而不需要任何字节码工具
Groovy,BeanShell或任何其他基于JVM的脚本语言都有这样的function,可以在运行时注入,修改,添加和运行代码。 实际上所有的脚本语言都被解释了,所以实际上这些都不是在运行时编译的。
Javassist几乎是用Java编写的完整的Java编译器,它完全由Java构成。 你不能一次给它一个完整的.java文件,但你可以给它个别函数的代码string,并将它们添加到相同的CtClass对象,它成为字节码,然后是一个java.lang.Class。
我刚刚发布了GigaLineCompile的0.1版,它将Javassist(编译器)和Beanshell(解释器)结合在一起,让您可以控制哪些代码需要优化以及何时进行优化。 在以后的版本中,它将在较小粒度的Javassist和Beanshell之间切换,所以如果你有许多共享一些子string的代码string,子string将被编译,而其他的部分在beanshell中运行。 它主要用于生成Java代码的人工智能,但它也是Clojure或Javassist / Beanshell的极端select。
Javassist,Beanshell和GigaLineCompile可以在这里下载(源码): http : //sourceforge.net/projects/gigalinecompile
保存自己的麻烦,并使用这里提到的BeanShell 执行文本文件中给出的Java代码 。
什么是BeanShell?
BeanShell是一个小型,免费,可embedded的Java源代码解释器,具有对象脚本语言function,用Java编写。 BeanShelldynamic地执行标准的Java语法,并通过普通的脚本方便的方式来扩展它,比如松散的types,命令,和像Perl和JavaScript那样的方法闭包。
您可以交互使用BeanShell进行Java实验和debugging,并以新的方式扩展您的应用程序。 脚本Java适用于各种各样的应用程序,包括快速原型,用户脚本扩展,规则引擎,configuration,testing,dynamic部署,embedded式系统甚至Java教育。
BeanShell很小且可embedded,因此您可以从Java应用程序中调用BeanShell以在运行时dynamic执行Java代码,或者在应用程序中提供可扩展性。 或者,您可以使用独立的BeanShell脚本来操作Java应用程序; dynamic使用Java对象和API。 由于BeanShell是用Java编写的,并且与应用程序在同一个虚拟机中运行,所以您可以自由地将“实时”对象的引用传递到脚本中,并将其作为结果返回。
简而言之,BeanShell是dynamic解释的Java,再加上一种脚本语言和灵活的环境,所有这些都被整合到一个干净的包中。
你可以像这样分叉进程
Process p = Runtime.getRuntime().exec("java -classpath "..." SomeClassContainingMain ...other arguments); //you need to consume the outputs of the command if output/error is large otherwise the process is going to hang if output/error buffer is full. and create a seperate thead for it (not created here). log.debug("PROCESS outputstream : " + p.getInputStream() ); log.debug("PROCESS errorstream : " + p.getErrorStream()); p.waitFor(); // Wait till the process is finished
并可以编译和运行它。