1、使用 jad命令反编译java类得到源代码文件 此时注意路径中斜杠只能使用反斜杠
jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java
2、使用mc内存编译命令编译源文件
mc /tmp/UserController.java -d /tmp
Mc 编译对于tomcat来说仍然可能会失败
Mc –c 类的classloaderhash或classloader全限定名(classloader hash根据sc –d 类名全限定名获取)。如(mc -c 10731e16 F:/git6/arthasroot/QueryFilter.java -d F:/git6/arthasroot)(‘>’ 符号可以将命令输出结果重定向到文件)
存在的问题是当源码文件中存在多个classloader时mc –c只能指定一个classloader,所以会编译不通过。此时只能使用手动编译。
ClassLoader –c (classloader哈希code)可以列出classloader已加载的类。
实操截图如下
3、redefine命令重新动态加载类(只能重载方法体)
redefine /tmp/com/example/demo/arthas/user/UserController.class
4、综合上述三个命令实现线上热修复(在无源码的情况下)的一般步骤。Jad反编译出类源码->对源码做出略微修改(比如加入调试日志等等)->使用Mc命令编译经过略微修改的源码为class文件,使用redefine重新定义类。(redefine只对方法体的修改有效)
实操截图如下