arthas线上日志打印

jad/mc/redefine线上热更新一条龙

开发时写下的 java 程序是高级语言,需要通过编译生成 .class 文件才能在 jvm 中运行。
所以在一个运行中的程序中进行热更新,需要先将它使用 jad [Java decompile]反编译,修改 .java 文件后使用 mc [Memory complile] 编译出 .class 文件,最后使用 redefine 命令更新虚拟机中的程序。
首先可以跟着教程来一次尝试
https://arthas.aliyun.com/doc/jad.html

反编译

$ jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java

修改文件

$ vim /tmp/UserController.java

查找加载的 ClassLoader

$  sc -d *UserController | grep classLoaderHash
 classLoaderHash   6bc28484

编译

$ mc -c 6bc28484 /tmp/UserController.java -d /tmp

热更新

$ redefine /tmp/com/example/demo/arthas/user/UserController.class
redefine success, size: 1

实际项目中反编译失败
但在工作中的项目中使用,发现出现了这个问题:反编译后的类不完整
查看通过 jad 命令反编译后的文件:

/*
 * Decompiled with CFR.
 *
 * Could not load the following classes:
 * ....
 */

在不完整的文件中进行修改后,进行 mc 命令编译,将会提示如下:

[arthas@7281]$ mc -c 6bc28484 /tmp/xxxx.java -d /tmp
Memory compiler error, exception message: Compilation Error
......
, please check $HOME/logs/arthas/arthas.log for more details.
Affect(row-cnt:0) cost in 884 ms.

可以看到,如果有复杂的类,并一定能够成功反编译,遭遇了失败,开始排查原因

反编译失败原因

开源的好处的是,大家可以一起参与到其中,提出问题和解决问题,在 github 项目 arthas 的 issue 中,通过关键字 jad 反编译 找到了原因
横云断岭 Arthas源码分析–jad反编译原理:

可能好巧不巧,实际项目中的代码,就遇上了这 1% 情况(顺便看了其它类,发现这种情况还不少…)
当时对于 jad 机制是有点不了解,所以想先通过上面的提示的工具 dumpclass 去精确获取 java 字节码,但奈何有些难用,尝试了几遍还是没能拿下来,于是开始换种思路。

方案二:直接拿到 .class 文件

既然前面的操作,获取修改后的 .class 文件,都是为了最后一步 redefine 所服务,那只要获取精确的 .class 文件就可以了,跳过前面的步骤也可以。
于是与一个前辈讨论后,他建议我使用 IDEA 工具编译后的 .class 文件
于是将本地代码进行修改,进行打包编译,得到想要的 .class 文件,然后将这个文件上传到测试环境,进行替换。
文件地址类似下图:

[arthas@63]$ redefine /tmp/xxxxxx.class
redefine success, size: 1

出现了成功的提示,同时进行了接口测试,发现执行的代码是修改后的逻辑!

总结

通过上面说的,正常来说只需要简单四步就能进行热更新
一、使用 jad 反编译出 .java 文件
二、编辑文件,修改逻辑
三、使用 mc 编译修改后的文件
四、使用 redefine 热更新
当然,也可能遇到 jad 反编译失败的场景,可以参考方案二,直接拿到修改后的 .class 文件,然后继续进行操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值