Bytebuddy - Перехватчик java .lang.RuntimeException конструктор - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь перехватить конструктор RuntimeException(String). Я пытаюсь использовать Advice как упомянуто здесь и показано здесь . Но методы onEnter(String message) или onExit(String message). Мой класс инструментов (в другой банке):

public class Instrumenting {

private static final String CLASS_NAME = "java.lang.RuntimeException";

public static void instrument(Instrumentation instrumentation) throws Exception {
    System.out.println("[Instrumenting] starting to instrument '" + CLASS_NAME + "'");

    instrumentation.appendToBootstrapClassLoaderSearch(new JarFile("C:\\Users\\Moritz\\Instrumenting\\dist\\Instrumenting.jar"));

    File temp = Files.createTempDirectory("tmp").toFile();
    ClassInjector.UsingInstrumentation.of(temp, ClassInjector.UsingInstrumentation.Target.BOOTSTRAP, instrumentation).inject(Collections.singletonMap(
        new TypeDescription.ForLoadedType(RuntimeExceptionIntercept.class),
        ClassFileLocator.ForClassLoader.read(RuntimeExceptionIntercept.class)));


    new AgentBuilder.Default()
            .ignore(ElementMatchers.none())
            .with(new AgentBuilder.InjectionStrategy.UsingInstrumentation(instrumentation, temp))
            .type(ElementMatchers.named(CLASS_NAME))

            .transform((DynamicType.Builder<?> builder, TypeDescription td, ClassLoader cl, JavaModule jm) -> 
                    builder
                            .visit(Advice.to(RuntimeExceptionIntercept.class)
                                            .on(ElementMatchers.isConstructor())
                            )
            ).installOn(instrumentation);

    System.out.println("[Instrumenting] done");
}

public static class RuntimeExceptionIntercept {

    @Advice.OnMethodEnter
    public static void onEnter(String message) throws Exception {
        System.err.println("onEnter: " + message);
    }

    @Advice.OnMethodExit
    public static void onExit(String message) throws Exception {
        System.err.println("onExit: " + message);
    }
}

}

Как это называется:

public class Main {

public static void premain(String agentArgs, Instrumentation instrumentation) throws Exception {
    Instrumenting.instrument(instrumentation);
}

public static void main(String[] args) throws MalformedURLException, IOException {
    new RuntimeException("message");
}

}

Вывод:

[Instrumenting] starting to instrument 'java.lang.RuntimeException'
[Instrumenting] done

Что я делаю не так?

1 Ответ

1 голос
/ 17 апреля 2020

Класс уже загружен, когда ваш агент работает, и вы не указали, например, RedefinitionStrategy.RETRANSFORM. Следовательно, ваш агент не будет пересматривать уже загруженные классы. Обратите внимание, что вы должны установить более конкретное значение c ignore matcher, чем это.

Кстати, в целевом классе есть совет, ваша инъекция не требуется.

...