背景
现场出现静态变量定义错误的情况,因为生产问题又不能重新发包。所以需要热部署更新类。
此处为转载
以某个界面为例
找到程序Action层或者Controller层
类的全路径:
com.ailk.openbilling.ams.action.freeResourceQuery.FreeResourceQueryActionImp
要观察的方法名:
queryFreeRes
1、热更新类
更新前:
(1)、将要反编译的文件 反编译到指定目录
命令:
jad com.ailk.openbilling.ams.action.freeResourceQuery.FreeResourceQueryActionImpl > /home/acctuser/cz/FreeResourceQueryActionImpl.java
结果:
(2)、修改文件内容
(3)、查找要更新的类的classLoader的哈希码
命令:
sc -d *FreeResourceQueryActionImpl | grep classLoaderHash
结果:
(4)、编译修改后的文件
命令:
mc -c 2b53eef4 /home/acctuser/cz/FreeResourceQueryActionImpl.java -d /home/acctuser/cz
结果:(编译报错)
问题解决
- 查看日志:
- 查看编译后的源码(发现头部多了好多类加载信息之类的东西)
- 重新反编译源码并且加上 --source-only 表示只输出源码
命令:
jad --source-only com.ailk.openbilling.ams.action.freeResourceQuery.FreeResourceQueryActionImpl > /XXX/XXX/cz/FreeResourceQueryActionImpl.java - 结果:(反编译成功)
- 重新修改.java文件后再次编译
- 又编译报错了
- 直接把本地修改好的.java文件放上去使用arthas编译成功生成了.class文件
- 继续热更新代码:
命令:
redefine /home/acctuser/cz/com/ailk/openbilling/ams/action/freeResourceQuery/FreeResourceQueryActionImpl.class - 结果失败:(提示增加或者删除了类或方法)
- 查看编译后的代码发现多了一个static{}和Log;
- 重新将反编译后的.java文件放到本地eclipse中将里面未指定泛型的报错(反编译会擦除泛型)地方修改掉,放到服务器重新使用mc -c 命令编译然后再热更新
热更新成功:
更新后:
一波三折终于热更新成功…