javassist重复增强及跟其他agent冲突问题

背景

有时候需要对服务进行调试,通过项目后门(接口)临时插入调试代码,用到javassistinsertAt,例如:

ctMethod.insertAt(45, "{ System.out.println(\"test\"); }");

调试完之后再清理掉调试的代码,用的是transform返回null的方式:

public static class ResetClassFileTransformer implements ClassFileTransformer {
    @Override
    public byte[] transform(
            ClassLoader loader,
            String className,
            Class<?> classBeingRedefined,
            ProtectionDomain protectionDomain,
            byte[] classfileBuffer) {
        return null;
    }
}

但是这种方式,如果在执行清理之后,项目没有重启的情况下,再次通过项目后门插入调试代码,之前被清理掉的增强代码又会出现了,比如执行以下增加之后:

ctMethod.insertAt(45, "{ System.out.println(\"test2\"); }");

执行结果是:

test
test2

原因是因为javassistClassPoolCtClass的增强会有缓存,所以我改为在清理时,同时执行CtClassdetach方法。
改了之后确实也解决了以上的问题,但是发现如果项目有其他的agent,并且该agent也用javassist做增强的话,在detach之后再次增强,agent的增强也会被清理掉。例如:

  1. 项目已有的agent里有insertBefore是打印出before,然后项目运行时通过后门执行insertAt打印test,这时候执行的结果是:

    before
    test
  2. 调试完之后执行清理ResetClassFileTransformer),这时候agent的增强还在,所以执行的结果是:

    before
  3. 这时候再次增强,通过insertAt打印test2,然而执行的结果是:

    test2

    agent的增强被清除了。

问题

要怎么做到可以重复的增强 -> 清除,但是又不影响项目已经引入的其他agent

阅读 1.6k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题