两个agent 用bytebuddy 对同一个类增强冲突问题

299 阅读1分钟

背景:

由于历史原因,我们有两个agent 用bytebuddy 对同一个类增强冲突报错: net.bytebuddy.pool.TypePool$Resolution$NoSuchTypeException: Cannot resolve type description for xxx$auxiliary$NqnfNQKN

报错原因

image.png

image.png 链接地址:github.com/raphw/byte-…

解决方案:

image.png

  new AgentBuilder
          .Default(byteBuddy)
          .with(AgentBuilder.LocationStrategy.ForClassLoader.WEAK)
          .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
          .type(ElementMatchers.<TypeDescription>nameStartsWith("com.demo"))
          .transform(new AgentBuilder.Transformer() {
              public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
                  return builder
                          .constructor(ElementMatchers.<MethodDescription>any())
                          .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration().to(new FirstAgentConstructInterceptor())));
              }
          })
          .with(new Listener("firstAagent"))
          .installOn(inst);
---------------------------------------------------------------------------------
public class Listener implements AgentBuilder.Listener {
    private String agentName;
    public Listener(String agentName) {
        this.agentName = agentName;
    }

    public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded, DynamicType dynamicType) {
        File debuggingClassesRootPath = new File("D:\\" + agentName + "\\");
        if (!debuggingClassesRootPath.exists()) {
            debuggingClassesRootPath.mkdirs();
        }
        try {
            dynamicType.saveIn(debuggingClassesRootPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

第二个代理中,我创建了一个新的 locationStrategy 并使用第一个代理字节码路径:

public class ApmClassFileLocationStrategy implements AgentBuilder.LocationStrategy{
    private final AgentBuilder.LocationStrategy defaultStrategy;
    private final String dir;

    public ApmClassFileLocationStrategy(AgentBuilder.LocationStrategy defaultStrategy, String dir) {
        this.defaultStrategy = defaultStrategy;
        this.dir = dir;
    }

    public static ApmClassFileLocationStrategy of(AgentBuilder.LocationStrategy defaultStrategy, String dir) {
        return new ApmClassFileLocationStrategy(defaultStrategy, dir);
    }

    public ClassFileLocator classFileLocator(ClassLoader classLoader, JavaModule module) {
        ClassFileLocator folderLocator = new ClassFileLocator.ForFolder(new File(dir));
        return new ClassFileLocator.Compound(defaultStrategy.classFileLocator(classLoader, module), folderLocator);
    }
}
---------------------------------------------------------------------------------
        new AgentBuilder
                .Default(byteBuddy)
                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                .with(new ApmClassFileLocationStrategy(AgentBuilder.LocationStrategy.ForClassLoader.WEAK, "D:\\firstAagent"))
                .with(new ErrorLoggingListener())
                .type(ElementMatchers.<TypeDescription>nameStartsWith("com.demo"))
                .transform(new AgentBuilder.Transformer() {
                    public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
                        return builder
                                .constructor(ElementMatchers.<MethodDescription>any())
                                .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.withDefaultConfiguration().to(new SecondeAgentConstructInterceptor())));
                    }
                })
                .with(new Listener("secondAgent"))
                .installOn(inst);

链接地址:github.com/raphw/byte-…

原因分析:

bytebuddy生成的代理类 xxx$auxiliary$NqnfNQKN 类的字节码信息并没有存放到磁盘中,而是在内存中。第一个egent 生成类的字节码并没有立即加载 。第二个类加载器在自己的加载路径中 找不到 xxx$auxiliary$NqnfNQKN 的字节码文件 ,就会报上面的错误 。