热更新是啥?

不停止java应用的情况下,直接替换虚拟机内的字节码;

用处?

比较多的是测试环境debug。测试环境并不像本地环境一样调试方便,需要编译,打包,部署。

步骤?

下面介绍下如何使用Arthas实现热更新。

先看一下用于测试的java程序:

/**
 * Hello world!
 *
 */
public class App 
{

    private double get(){
        return Math.random();
    }

    private void run(){
        for (int i = 0; i < 1000000000; i++) {
            try {
                Thread.sleep(5000);
                System.out.println(get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main( String[] args ) throws IOException {

        new App().run();
    }
}

使用maven打出一个可以可以直接运行的jar包,并且运行。

每隔一秒打印一个0-1之间的小数,可以看到输出如下:

⇒  java -jar testMaven1-1.0-SNAPSHOT.jar
0.7839043482348526
0.11390699050234909
0.9107929624621809
0.9384221341175452

 

下面开始热更新:

java -jar arthas-boot.jar

使用上面的命令启动arthas。并且选择之前的java程序进程:

miracle@localhost:~/arthas|⇒  java -jar arthas-boot.jar
[INFO] arthas-boot version: 3.1.1
[INFO] Found existing java process, please choose one and hit RETURN.
* [1]: 12683 org.jetbrains.idea.maven.server.RemoteMavenServer
  [2]: 17166 testMaven1-1.0-SNAPSHOT.jar
  [3]: 12655
2

1)使用jad命令反编译:

jad --source-only com.liyao.App > App.java

需要加上--source-only参数,不然会在源文件中带上classloader的信息,导致无法直接编译。

后面是全限定类名。

结果默认是终端输出,所以重定向到文件中。

 

2)修改java源文件:

这里直接使用vim,在get方法的返回值上加100。

 27     private double get() {
 28         return 100 + Math.random();
 29     }

 

3)使用mc命令编译新的java文件:

mc App.java

$ mc App.java
Memory compiler output:
/Users/miracle/test/mvn/testMaven1/target/com/liyao/App.class
Affect(row-cnt:1) cost in 463 ms.

 

4)使用redefine命令重新加载字节码文件:

redefine /Users/miracle/test/mvn/testMaven1/target/com/liyao/App.class

redefine success, size: 1

 

然后再看下之前的java应用的输出:

0.1164675982131923
0.8292291692991027
0.528215214956233
0.8430507304634605
0.7346896134684758
0.8252403266819852
0.05921801561579343
100.38541391802795
100.88354978571243
可以看到,已经是更新之后的返回值了。

 

redefine命令的限制:

不能新增/删除成员变量或者方法。

否则会报错:

redefine error! java.lang.UnsupportedOperationException: class redefinition failed: attempted to add a method

redefine error! java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐