【问题标题】:Referring to a dynamically added method in ByteBuddy AgentBuilder引用 ByteBuddy AgentBuilder 中动态添加的方法
【发布时间】:2025-12-21 01:10:07
【问题描述】:

我想用Byte Buddy实现如下场景

  1. 在抽象类中定义新的构造函数
  2. 在调用 #1 的子类型中创建新方法 但是我遇到了一个问题,即 #2 的转换器无法找到 #1 中定义的方法。

更详细的设置说明如下:

我有课程BaseA

public abstract class Base {
  protected Base() {}
  protected Base(String s, Object o) {...}
}
public abstract class A {
  protected A() {}
}

我想给A添加另一个构造函数,相当于

  protected A(String s, Integer i) {
    super(s, i);
  }

所以我写了

new AgentBuilder.Default().type(named("A"))
  .transform((builder, typeDescription, classLoader, module) ->

    builder.defineConstructor(Visibility.PROTECTED)
        .withParameter(String.class)
        .withParameter(Integer.class)
        .intercept(
            MethodCall.invoke(isConstructor().and(takesArguments(String.class, Object.class)))
              .withArgument(0, 1)))
  .installOn(instrumentation);

如果我使用此代理运行我的代码,我可以看到在运行时添加的新构造函数。

现在我想在另一个类B 中引用这个新添加的构造函数。

public class B extends A {

   // I want to add this method
   newMethod() {
     super("str", 0)
   }
}

所以我写了

new AgentBuilder.Default().type(isSubTypeOf(A.class)))
  .transform((builder, typeDescription, classLoader, module) ->

    builder.defineMethod("newMethod", typeDescription, Visibility.PUBLIC)
      .intercept(
          MethodCall.invoke(isConstructor().and(takesArguments(String.class, Integer.class)))
            .with("str")
            .with(0)))
  .installOn(instrumentation);

但是,我收到如下错误

java.lang.IllegalStateException: class B does not define exactly one virtual method or constructor for (isConstructor() and hasParameter(hasTypes(erasures(containing(is(class String), is(class Integer)))))) but contained 0 candidates: []

我可以不引用我在以前的转换器中添加的方法吗? (第一次使用ByteBuddy)

【问题讨论】:

    标签: byte-buddy


    【解决方案1】:

    问题是另一个类需要从存储的类文件以旧格式表示的类路径中定位。与其使用隐式浏览层次结构的匹配器,不如显式提供方法,例如使用MethodDescription.Latent

    【讨论】: