目前 redefine功能会和 trace/watch/ jad 等功能冲突。
reset命令对redefine的类无效。如果想重置,需要redefine原始的字节码。
redefine命令和jad/watch/trace/monitor/tt等命令会冲突。执行完redefine之后,如果再执行上面提到的命令,则会把redefine的字节码重置。
原因是jdk本身redefine和Retransform是不同的机制,同时使用两种机制来更新字节码,只有最后修改的会生效。
尽管是因为jdk自身机制问题,但考虑基于retransform重新实现一个redefine功能。 新的实现,可以让 redefine 和 watch/jad 等功能不冲突。
现在问题是:
一、是否直接以 retransform 的方式重新实现 redefine命令?
二、是否使用新命令名?
目前的 watch/trace/monitor/tt 是针对原始的字节码进行增强, 如果redefine之后缓存一份字节码,后续的 watch/trace/monitor/tt 基于这个来做呢?
只是解决redefine 和 watch/jad 等功能的冲突?
目前的 watch/trace/monitor/tt 是针对原始的字节码进行增强, 如果redefine之后缓存一份字节码,后续的 watch/trace/monitor/tt 基于这个来做呢?
这个容易起冲突。 watch 和 redefine 命令可能多次执行,并且执行的顺序也不一样。
只是解决redefine 和 watch/jad 等功能的冲突?
现在一个常见的问题,就是 redefine 之后,用户再用 jad 来确认是否生效,结果就失效了。
我觉得可以搞个新命令就叫retransform(虽然不太好记),然后把原来的redefine命令加上@Hidden隐藏起来弃用掉,文档中也去掉redefine命令。当用户使用旧的redefine命令时输出一段警告,提示用户此命令可能带来的问题并链接到某个 issue 或 wiki 中,并且推荐用户使用retransform。这样新旧命令都能用,而且还能和 JDK 自身的机制名称保持一致
目前的 watch/trace/monitor/tt 是针对原始的字节码进行增强, 如果redefine之后缓存一份字节码,后续的 watch/trace/monitor/tt 基于这个来做呢?
这个容易起冲突。 watch 和 redefine 命令可能多次执行,并且执行的顺序也不一样。
每次redefine生成一个快照/版本信息, 其他非redefine优先取快照,没有就取jvm的字节码. reset可以针对版本恢复
不过这种场景有一个缺陷就是,字节码的存储问题
增加了retransform 命令,测试包:
参考: https://github.com/alibaba/arthas/blob/master/site/src/site/sphinx/retransform.md
更新了下,打印 TransformCount,表示被触发的次数
@hengyunabc 测试了三次 最后一次故意增加field retransform -l 也会存在 ,jad 反编译时最后一次的增加field的代码 这个有点奇怪。
@hengyunabc 测试了三次 最后一次故意增加field retransform -l 也会存在 ,jad 反编译时最后一次的增加field的代码 这个有点奇怪。
这里好像没有太好的办法。因为只能先记录,再触发 retransform 。尽管 retransform 可能失败。
Most helpful comment
我觉得可以搞个新命令就叫
retransform(虽然不太好记),然后把原来的redefine命令加上@Hidden隐藏起来弃用掉,文档中也去掉redefine命令。当用户使用旧的redefine命令时输出一段警告,提示用户此命令可能带来的问题并链接到某个 issue 或 wiki 中,并且推荐用户使用retransform。这样新旧命令都能用,而且还能和 JDK 自身的机制名称保持一致