@Override не работает при использовании ByteBuddy disableClassFormatChanges - PullRequest
0 голосов
/ 12 января 2019

Я пишу 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 голосов
/ 23 апреля 2019

Ответ

Я думаю, что проблема там в вашей конфигурации.

Можете ли вы попробовать следующий (похоже на ваш, но без .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);
  }

приписка

, чтобы сделать более понятный цикл, вы можете использовать отслеживание ваших звонков, например

  @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");
  }

возможный может быть полезен для отслеживания экземпляра, где был вызван метод.

...