windows环境下使用arthas不启动服务替换文件

场景:

windows环境,如果现场环境客户正在使用项目,如果要替换项目中的一个class文件,但是又不能重启服务改怎么处理,今天介绍使用arthas中的retransform命令动态替换及使用注意的事项。

环境:

windows,arthas,测试项目 

替换前:

准备测试文件LoginController.class,准备对如下方法进行简单的修改替换

windows环境下使用arthas不启动服务替换文件_第1张图片

启动

启动时加上-Dfile.encoding=UTF-8 保证控制台不会出现中文乱码

java -Dfile.encoding=UTF-8 -jar arthas-boot.jar

windows环境下使用arthas不启动服务替换文件_第2张图片

反编译:

将线上LoginController.class文件使用jad反编译到指定的文件中

jad --source-only com.gisquest.platform.rest.sys.LoginController > D:/temp/LoginController.java

获取类加载器 

获取线上加载LoginController.class的类加载hashcode.

sc -d com.gisquest.platform.rest.sys.LoginController

windows环境下使用arthas不启动服务替换文件_第3张图片

对反编译的文件修改

windows环境下使用arthas不启动服务替换文件_第4张图片

mc内存编译

使用mc命令将反编译的.java文件变成对应的.class文件

mc -c 27647ad0 D://temp/LoginController.java -d D://temp

windows环境下使用arthas不启动服务替换文件_第5张图片

Memory compiler error, exception message: Compilation Error

本地编译:

这里没有成功只能放到项目中编译了

windows环境下使用arthas不启动服务替换文件_第6张图片

 redefine命令热加载

验证

观察到内存中加载的已经是修改后的方法,因此验证成功!!!!

windows环境下使用arthas不启动服务替换文件_第7张图片

相关问题及验证

问题一:mc命令将修改后的loginController.java文件编译成LoginController.class时为什么报错

问题二:redefine 和 retransform命令热加载区别

相同点:

  • 正在跑的函数,没有退出不能生效,比如下面新增加的System.out.println,只有run()函数里的会生效

  • 不允许新增加 field/method

  • 加载外部的.class 文件,redefine jvm 已加载的类。

区别:

redefine命令和jad/watch/trace/monitor/tt等命令会冲突。执行完redefine之后,如果再执行上面提到的命令,则会把redefine的字节码重置

如果多次执行 retransform 加载同一个 class 文件,则会有多条 retransform entry.

推荐使用retransform命令

拓展

sc 命令搜索jvm加载的类信息

 sc *LoginController 

sc *LoginController -d | grep classLoaderHash

sm命令搜索jvm加载的方法信息

sm查询一个类中的所有方法

sm *LoginController -d  | grep method-name

windows环境下使用arthas不启动服务替换文件_第8张图片

sm查询一个类中的所有方法中具体一个方法

sm *LoginController -d  | grep method-name | grep sendVerificationCode

ognl命令

1.查看类中静态变量的信息

ognl @com.gisquest.platform.rest.sys.LoginController@deptUserProperties

原因是LoginController存在多个类加载器,需要指定classLoaderHash

windows环境下使用arthas不启动服务替换文件_第9张图片

如果静态变量是集合,可查看集合中key对应的value信息

 ognl -c 6375bfd4 "@com.gisquest.platform.rest.sys.LoginController@deptUserProperties['id']"

windows环境下使用arthas不启动服务替换文件_第10张图片注意:

@class@Field时,引号的使用

你可能感兴趣的:(java)