javassist 运行时动态修改代码

遇到一个有意思的任务:在运行时修改 class 行为.
顺理成章,把目光移到了 javassist上.

javassist是一个java class 处理工具,常用于实现动态代理.常用来在各种框架里实现代理功能.

优点:

  • 0 操作class的能力
  • 1 可以运行时修改class文件
  • 2 广泛被依赖(hibernate,mybatis都会应用它的jar包,无需再次引用)

相关代码:

//监听 8000 端口,在启动参数里设置
//java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
HotSwapper hs = new HotSwapper(8000);

// 
ClassPool cp = ClassPool.getDefault();
//获取类
String clsName = C2.C8.class.getName();
CtClass cc = cp.get(clsName);
//获取方法
CtMethod m = cc.getDeclaredMethod("getSerial");
//重写方法
m.setBody("{ return getM(); }");
//调用一次
System.out.println(C2.C8.getM());
hs.reload(clsName, cc.toBytecode());
//再调用一次
System.out.println(C2.C8.getM());

注意:

  • 0 JVM 不允许一个class有多个不同版本.修改class需要注意.
  • 1 需要开启JPDA支持加载class java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
  • 2 开启JPDA 会影响debug

文档:

http://www.javassist.org/tutorial/tutorial.html#hotswap

If the JVM is launched with the JPDA (Java Platform Debugger Architecture) enabled, a class is dynamically reloadable. After the JVM loads a class, the old version of the class definition can be unloaded and a new one can be reloaded again. That is, the definition of that class can be dynamically modified during runtime. However, the new class definition must be somewhat compatible to the old one. The JVM does not allow schema changes between the two versions. They have the same set of methods and fields.

http://www.javassist.org/html/javassist/util/HotSwapper.html

For Java 5, java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000 Note that 8000 is the port number used by HotSwapper. Any port number can be specified. Since HotSwapper does not launch another JVM for running a target application, this port number is used only for inter-thread communication. Furthermore, JAVA_HOME/lib/tools.jar must be included in the class path. Using HotSwapper is easy. See the following example: CtClass clazz = ... byte[] classFile = clazz.toBytecode(); HotSwapper hs = new HostSwapper(8000); // 8000 is a port number. hs.reload("Test", classFile);
reload() first unload the Test class and load a new version of the Test class. classFile is a byte array containing the new contents of the class file for the Test class. The developers can repatedly call reload() on the same HotSwapper object so that they can reload a number of classes. HotSwap depends on the debug agent to perform hot-swapping but it is reported that the debug agent is buggy under massively multithreaded environments. If you encounter a problem, try HotSwapAgent.

项目地址:https://github.com/jboss-javassist/javassist
官网:http://www.javassist.org/

转载于:https://my.oschina.net/zhouxiang/blog/3101856

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值