使用ByteBuddy disableClassFormatChanges时,@ Override不起作用

时间:2019-01-12 20:36:39

标签: java bytecode byte-buddy javaagents

我正在编写一个Java代理,当我将Byte Buddy与以下选项一起使用时,遇到了一个很有趣的问题:

net.bytebuddy.agent.builder.AgentBuilder#disableClassFormatChanges

问题在于,无论是否在超类的子级中重写超类的方法都无关紧要,总是调用超类中的一个。

代理商:

public class Main {


public static void premain(String agentOps, Instrumentation inst) {
    instrument(agentOps, inst);
}

public static void agentmain(String agentOps, Instrumentation inst) {
    instrument(agentOps, inst);
}

private static void instrument(String agentOps, Instrumentation inst) {
    new AgentBuilder.Default().with(new Eager())
            .disableClassFormatChanges()
            .type((any()))
            .transform((builder, typeDescription, classLoader, module) ->
                    builder.method(any()).intercept(Advice.to(LoggingAdvice.class)))
            .installOn(inst);
}

public static class LoggingAdvice {
    @Advice.OnMethodEnter
    static void enter(@Advice.Origin String method) {
    }

    @Advice.OnMethodExit
    static void exit(@Advice.Origin String method) {
    }
}

}

以及我用于测试的类:

超级:

public class Test1 {

public void test() {
    System.out.println("Test 1");
}

}

孩子:

public class Test2 extends Test1 {

@Override
public void test() {
    System.out.println("Test 2");
}

}

主类:

public class Main {

public static void main(String[] args) {
    new Test1().test();
    new Test2().test();
}

}

结果是:

Test 1
Test 1

预期结果:

Test 1
Test 2

没有代理,一切都会按预期进行。
我尝试玩ElementMatcher,但没有获得成功的结果。

这里可能是什么问题?

1 个答案:

答案 0 :(得分:1)

答案

我认为您的配置存在问题。

您能不能请下一个(类似于您的一个,但是没有.disableClassFormatChanges()):

  private static void instrument(String agentOps, Instrumentation inst) {
    new AgentBuilder.Default()
        .with(new Eager())
        .type((any()))
        .transform((builder, typeDescription, classLoader, module) ->
            builder
                .method(any())
                .intercept(Advice.to(LoggingAdvice.class)))
        .installOn(inst);
  }

P.S。

要使周期更清晰,您可以使用例如跟踪电话

  @Advice.OnMethodEnter
  static void enter(@Advice.Origin String method) {
    System.out.println("enter");
  }

  @Advice.OnMethodExit
  static void exit(@Advice.Origin String method) {
    System.out.println("exit");
  }

可能对跟踪调用方法的实例很有用。