通过热插拔机制在运行时更改方法

假设我们有一个简单的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);
   }
}

编译并运行后,输出结果如下:

今天是一个愉快的一天,数字为0

今天是1号的好日子

今天是2号的好日子

今天是3号的美好一天

...

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

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

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

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

  • 运行原始程序
  • 写修改后的版本
  • 使用命令行程序,连接到正在运行的JVM并替换现有的方法
  • 这样在运行时会发生这种情况:

    今天是一个愉快的一天,数字为15000

    今天是一个愉快的一天,数字为15001

    今天是一个更好的日子,15002

    今天是更好的一天,15003

    ...

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

    注意:我知道诸如字节码操作(cglib),aspectJ,jRebel,JMX,Java EE等中方法的热插拔等技术存在,但它们不是我所想的。 想想Erlang。


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


    你可以通过类加载器来完成。 例如,如果您熟悉像在Tomcat中一样的Servlet容器,在开发中修改它们时会重新加载页面。 这里是在java中创建动态代码的一个很好的解释。 它不仅解释了加载,而且还动态编译源代码。 您应该能够将涵盖的概念应用于您想要使用的任何重新加载代码的策略。


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

    只要变化不是结构性的,任何数量的类都可以被热切换。 方法体更改通常易于轻松进行。 代码可以通过通过shell或Eclipse运行ant脚本来激活。

    在工作中,我使用一个脚本,通过比较类文件的时间戳来自动更改代码更改。 这与项目页面上的示例类似,只显示了一个简单的示例,只有热插拔更改了类。

    附加说明:这利用了JPDA。

    链接地址: http://www.djcxy.com/p/86079.html

    上一篇: Change a method at runtime via a hot swap mechanism

    下一篇: Postgresql very slow query on indexed column