【问题标题】:Bytebuddy - Intercept java.lang.RuntimeException constructorBytebuddy - 拦截 java.lang.RuntimeException 构造函数
【发布时间】:2020-04-17 11:24:04
【问题描述】:

我试图拦截构造函数RuntimeException(String)。我正在尝试使用Advice,如提到的here 和显示的here。但是方法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

我做错了什么?

【问题讨论】:

    标签: java agent byte-buddy


    【解决方案1】:

    当您的代理运行时,该类已经加载并且您没有指定例如RedefinitionStrategy.RETRANSFORM。因此,您的代理不会重新考虑已加载的类。请注意,您应该设置一个更具体的忽略匹配器。

    顺便说一句,advice 是内联在目标类中的,不需要你的注入。

    【讨论】:

    • 添加 RedefinitionStrategy.RETRANSFORM 并没有解决我的问题。这里还有什么问题? ://
    • 你加了监听看看有没有报错?
    • 你是对的,我添加了一个监听器并得到以下错误No advice defined by class instrumenting.Instrumenting$RuntimeExceptionIntercept
    • 你的建议类可能也在引导加载程序上吗?这可以解释为什么没有发现注释。
    • 你说得对,我将RuntimeExceptionIntercept 类移动到另一个文件,从而修复了错误。但现在我得到java.lang.IllegalStateException: Cannot assign java.lang.Throwable arg0 to class javalang.String。我是否必须为RuntimeException 的每个构造函数提供onEnteronExit?或者我做错了什么?感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多