Javasist热加载

HotSwapper热加载

public class HotSwapperTest {
    public static void main(String[] args) throws NotFoundException, CannotCompileException, IOException, IllegalConnectorArgumentsException {
        Person person = new Person();
        System.out.println(Person.class.getClassLoader());

        /* 创建线程循环调用Person类的foo方法 */
        new Thread(() -> {
            System.out.println(Person.class.getClassLoader());
            while (true){
                person.foo();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        /* Javassist修改Person类的foo方法 */
        ClassPool classPool = ClassPool.getDefault();
        System.out.println(classPool.getClassLoader());
        CtClass ctClass = classPool.get(person.getClass().getName());

        CtMethod ctMethod = ctClass.getDeclaredMethod("foo");
        ctMethod.setBody("System.out.println(\"change\");");

        /*
         * HotSwapper热修改Person类,需要监听 8000 端口,在启动参数里设置
         * java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
        */
        HotSwapper hs = new HotSwapper(8000);
        hs.reload(person.getClass().getName(), ctClass.toBytecode());
    }
}

javassist.tools.HotSwapper,是 javassist 的包中提供的热加载替换类操作。在执行时需要启用 JPDA(Java平台调试器体系结构)。
最后使用 hs.reload 执行热加载替换操作,这里的 ctClass.toBytecode() 获取的是处理后类的字节码。

引用 tools.jar

pom.xml:

<dependency>
  <groupId>com.sun</groupId>
  <artifactId>tools</artifactId>
  <version>1.4.2</version>
  <scope>system</scope>
  <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>

配置-agentlib

启动HotSwapperTest 的 VM options 添加配置项

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

用于启用 JPDA(Java平台调试器体系结构)

运行结果

Listening for transport dt_socket at address: 8000
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader@18b4aac2
foo
sun.misc.Launcher$AppClassLoader@18b4aac2
foo
foo
foo
foo
foo
change
change

结果看出,主线程、子线程、Javassist默认的 ClassLoader 都是 AppClassLoader
重写方法后,hs.reload 执行热加载替换操作,后续 foo 方法执行体改变。

https://www.dandelioncloud.cn/article/details/1466967080951181313
http://events.jianshu.io/p/041a42d9ca66
https://blog.csdn.net/H291850336/article/details/103187408
https://blog.csdn.net/jiangguilong2000/article/details/73924206
https://blog.csdn.net/blueheartstone/article/details/113512479
http://www.360doc.com/content/21/1213/11/78097014_1008492520.shtml

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会叫的狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值