2011-03-15 46 views
1

我注意到了JDK 7中的编译器API。这是否意味着Java程序可以重新编译和更改正在运行的程序的定义?JDK 7允许程序改变它自己的代码吗?

目前我知道像JavaRebel这样的产品可以做到这一点,但是提供产品的免费下载不包括Javarebel,这是一款付费产品。

回答

8

编译器API是在Java中已有6

我们无法改变已经加载类的代码 - 热代码替换将仍然被限制在调试,但是我们可以从Java应用程序编译源代码和在运行时加载新创建的类。

3

是的,这是可能的。一种方法是编写一个专门的类加载器,并使用像ASM这样的字节码增强工具,并在运行时更改应用程序的某些部分。使用javaagentASM或类似的东西也可以达到同样的效果。

+0

..但这与编译器API无关。如我错了请纠正我。 – 2011-03-15 10:41:50

+1

如果OP只对使用javac或编译器API产生字节码感兴趣,那么你是对的。但是如果他的目标是在运行时动态生成字节码,那么他可以使用ASM(或Javassist),也可以使用或不使用javaagent。顺便说一下,是与JVM下载捆绑在一起的编译器API,还是仅与JDK捆绑在一起? – Behrang 2011-03-15 10:53:42

+0

这就是我在网上找到的地方:* Java编译器的实现可以在tools.jar文件中找到(通常可以在 \ lib \ tools.jar中找到)*。所以我们需要一个JDK。 – 2011-03-15 12:28:42

3

据我所知,Java 7没有引入其他自修改方法。

某些影响可以通过使用编译器API和ClassLoaders完成,而其他一些影响可以使用JVM TI完成。

但据我所知,Java 7并没有对这些API做任何重大修改。

3

有一个项目,JRebel的类级重装功能添加到OpenJDK 7的,虽然它不是当前打开的JDK 7的一部分:Dynamic Code Evolution VM(DCEVM)

它是通过正常JVMTI类重新定义机制。

+1

DCEVM就像Rebel一样不是真的正确。不,这是两种不同的方法。 JRebel是执行代码转换以实现类重新加载的代理,它也映射工作空间并与框架集成。 DCEVM代替了复杂类重新定义的虚拟机级别方法(在调试模式下)。所以第一个是纯Java,后者是VM的补充 - 两个完全不同的东西 – 2011-03-22 11:31:27

+1

是的,机制是不同的,但目标是相同的。 DCEVM是VM修改,但它使用标准的JVMTI接口,只是扩展允许的类更改的种类。 – Ramon 2011-03-23 07:24:29

+0

有关版本1.7和1.8,请参阅https://dcevm.github.io/ – cquezel 2014-05-01 18:50:43

2

Javeleon提供了沿着这些方向的功能;它可以免费获得,但不能免费再分发。

编译器API(JSR 199)与代码重新加载或自我修改无关,除非希望以某种方式加载新字节码的程序可能使用199来从Java源代码构建该字节代码,而不是使用像ASM这样的汇编程序API。

更新:

看起来Javelon不再可用,因为它已被zeroturnaround(JRebel的创造者)

从Javelon主页获得:

注:Javeleon将不再可作为独立产品下载。

相关问题