通过热交换机制在运行时更改方法

dar*_*ioo 56 java runtime hotswap

假设我们有一个简单的Java程序,它只包含一个类:

public class HelloWorld {

   private static void replacable(int i) {
      System.out.println("Today is a nice day with a number " + i);
   }        

   public static void main(String[] args) throws Exception {
      for(int i = 0; i < 100000; ++i) {
      replacable(i);
      Thread.sleep(500);
   }
}
Run Code Online (Sandbox Code Playgroud)

在编译并运行之后,输出将是:

今天是0号的好日子

今天是一个美好的一天,1号

今天是2号球员的好日子

今天是一个美好的一天,3号

...

我的问题:是否存在(或者是否存在)replacable在运行时交换方法的某种方式?有点像HelloWorld用新版本编写另一个版本replacable,编译它,然后在已经运行的JVM中编写旧版本?

所以,如果我像这样编写新版本:

private static void replacable(int i) {
   System.out.println("Today is an even nicer day with a number " + i);
}  
Run Code Online (Sandbox Code Playgroud)

是否有类似于Erlang的热代码交换,我可以这样做:

  1. 运行原始程序
  2. 写修改版
  3. 使用命令行程序,连接到正在运行的JVM并替换现有方法

这样,在运行时,这将发生:

今天是一个美好的一天,15000

今天是一个美好的一天,数量为15001

今天是一个更好的一天,数量为15002

今天是一个更好的一天,15003号

...

假设上面的程序是独立的,在标准的Java SE环境中运行,类路径上没有别的东西,所以它几乎是一个Hello世界风格的程序.

注意:我知道存在字节码操作(cglib),aspectJ,jRebel,JMX,Java EE等方法的热交换等技术,但它们并不是我想到的.想想二郎.

Aru*_*run 38

您可以使用开源HotSpot VM或商业JRebel IDE插件轻松实现目标(此处查看比较表).


M. *_*sup 15

你可以通过类加载器来完成.例如,如果您熟悉诸如tomcat之类的Servlet容器,那么在开发过程中修改它们时会重新加载页面.以下是在java中创建动态代码的一个很好的解释.它不仅可以解释加载,还可以动态编译源代码.您应该能够将所涵盖的概念应用于任何重新加载要使用的代码的策略.


And*_*ndy 9

我在很多项目中都使用过这个hotswap ant任务.目标java应用程序可以通过Ant,Eclipse,命令提示符或任何其他方式启动,只要它在调试模式下启动并打开相应的端口即可.链接页面提供了有关如何通过Ant执行此操作的说明.

只要更改不是结构化的,任何数量的类都可以被热交换.方法体的变化通常很容易变热.通过shell或Eclipse运行ant脚本可以彻底改变代码.

在工作中,我利用一个脚本,通过比较类文件的时间戳来自动热交换代码更改.这类似于项目页面上的示例,该示例显示了一个只有hotswaps更改类的简单示例.

附加说明:这利用了JPDA.