Возможно ли перехватить метод, у которого нет аргументов, с использованием @Advice .Все аргументы в ByteBuddy?

#java #byte-buddy #javaagents

#java #байт-приятель #javaagents

Вопрос:

Я пытаюсь создать систему ведения журнала, которая будет использовать ряд методов. Некоторые из методов, которые я перехватываю, имеют 0 аргументов, другие много. Мой вопрос: могу ли я создать универсальный @Advice.OnMethodEnter , который мог бы фиксировать аргументы, используя @Advice.AllArguments ByteBuddy?

Метод выглядит так:

 @Advice.OnMethodEnter
public static void intercept(@Port int port, 
                             @Host String host, 
                             @Advice.Origin("#t:#m") String signature, 
                             @Advice.AllArguments Object[] arguments) 
{
    AgentHelper.log(host, port, signature, Arrays.toString(arguments));
}
 

Все работает нормально, когда аннотация @Advice.AllArguments отсутствует, но как только я ее ставлю, все методы без аргументов игнорируются.

Я также попытался проверить, есть ли явная ошибка, вызванная использованием:

 new AgentBuilder.Default()
    ...
    .with(AgentBuilder.Listener.StreamWriting.toSystemOut().withErrorsOnly())
    .with(AgentBuilder.InstallationListener.StreamWriting.toSystemOut())
    ...
 

но это не показало никакой ошибки. Должен ли я создавать перехватчик в каждом конкретном случае или есть способ получить это поведение способом, который я не понимаю?

Ответ №1:

Да, это должно работать без проблем:

 public class Example {
  public static void main(String[] args) {
    new AgentBuilder.Default()
      .disableClassFormatChanges()
       .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
       .type(is(Target.class))
       .transform((builder, typeDescription, classLoader, module) -> 
               builder.visit(Advice.to(Example.class).on(isMethod())))
       .installOn(ByteBuddyAgent.install());

    new Target().method();
  }

  @Advice.OnMethodEnter
  public static void intercept(@Advice.AllArguments Object[] arguments) {
    System.out.println("Intercepted: "   Arrays.asList(arguments));
  }

  public static class Target {
    public void method() { }
  }
}
 

При вызове будет выведен пустой список.

Комментарии:

1. Здравствуйте, спасибо за ответ, поэтому после расследования я понял, что это типичная проблема с интерфейсом клавиатуры. В какой-то момент я использовал перехват вместо посещения, хотя я не совсем уверен, почему он ведет себя так по-разному, это решило проблему. Мне нужно будет выполнить несколько тестов, чтобы увидеть, как эта ошибка соотносится с эффектом, который я наблюдал. Еще раз спасибо!