最近在学习java的javaagent给函数插桩。
从github上随便找了个样例程序,发现UserDAO这个类在jsp预编译完成后(即第二次启动tomcat)怎么都插不上桩,只有删除jsp生成的class后才能正常插桩。
在transform里输出处理的所有类名,发现完全没有UserDAO这个类。
起初怀疑是ClassLoader的问题,但折腾了一天没有任何改变。
最后排查到了这里:
1 | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAME) { |
将COMPUTE_FRAME与SKIP_FRAME移除后,正常了
原因
根据这个回答描述的,COMPUTE_FRAME会尝试修改代码,让代码不用执行到原来的类中,也就造成了无缓存时,从原有文件读取代码,经过了javaagent的处理;而有缓存时,由于优化了路径,没有执行原来的类,也就没有读取并调用javaagent了,导致了缺少对应函数的插桩。
刚开始学习java,有什么不对欢迎指出owo