Как вызвать оригинальный метод после MethodDelegation с помощью агента java и байта? - PullRequest
0 голосов
/ 30 января 2020

В последнее время я начинаю играть с байтовым приятелем и пытаюсь поймать некоторые Java методы. Я пытаюсь подключить readBoolean из java .io.ObjectInputStream. Это работает нормально, если я всегда возвращаю true или false. Однако я не могу заставить его работать, если я только хочу, чтобы первый вызов возвратил false, а остальные возвращают что-либо из исходного перехваченного метода. Вот мой код:

    new AgentBuilder.Default()
            .with(RedefinitionStrategy.RETRANSFORMATION)
            .with(InitializationStrategy.NoOp.INSTANCE)
            .with(TypeStrategy.Default.REDEFINE)
            .ignore(new AgentBuilder.RawMatcher.ForElementMatchers(nameStartsWith("net.bytebuddy.").or(isSynthetic()), any(), any()))
            .with(new Listener.Filtering(
                    new StringMatcher("java.io.ObjectInputStream", StringMatcher.Mode.EQUALS_FULLY),
                    Listener.StreamWriting.toSystemOut()))
            .type(named("java.io.ObjectInputStream"))  //class
            .transform((builder, type, classLoader, module) ->
                            builder.method(ElementMatchers.nameContains("readBoolean"))
                                   .intercept(MethodDelegation.to(INTERCEPTOR_CLASS))
            )
            .installOn(inst);

В INTERCEPTOR_CLASS работает только следующее:

public static boolean readBoolean(@Origin Method m) throws Exception{
    LOGGER.log(Level.INFO, "In "+ m.getName());
    return true;
}

Это неправильно и имеет некоторое запущенное исключение, если я пытаюсь использовать @Super Callable.

Также, если я пытаюсь использовать Advice.to (INTERCEPTOR_CLASS) и @ Advice.OnMethodExit, я не могу использовать @ Advice.Return, чтобы установить для возврата значение true или false. Кажется, не работает установка возвращаемого значения для примитива.

Нет изменений, если я изменю TypeStrategy.Default.REDEFINE на TypeStrategy.Default.REBASE

Я читаю документ снова и снова, Кажется, до сих пор нет понятия. Спасибо, что указали мне правильное направление.

1 Ответ

0 голосов
/ 30 января 2020

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

Совет, вероятно, является лучшим вариантом для вас. Это должно работать, если нет, пожалуйста, создайте проект репродуктора. Если вы хотите использовать делегирование, вам необходимо зарегистрировать bootstrap -кабельную стратегию впрыска .

...