使用 bytebuddy 拦截错误构造函数

Intercept Error constructor with bytebuddy

出于某种原因我还不能解决问题,我的代理没有拦截 java 个 LinkageError 实例。

代理代码:

import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.SuperMethodCall;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.instrument.Instrumentation;

public class MyAgent {
    public static void premain(String arguments, Instrumentation instrumentation) {
        new AgentBuilder.Default()
            .type(ElementMatchers.isSubTypeOf(LinkageError.class))
            .transform((builder, type, classLoader, module) ->
                    builder.constructor(ElementMatchers.isDefaultConstructor())
                            .intercept(SuperMethodCall.INSTANCE.andThen(MethodDelegation.to(MyInterceptor.class)))
            ).installOn(instrumentation);
    }
}

拦截器代码:

public class MyInterceptor {
    @RuntimeType
    public static void intercept(@Origin Constructor<?> constructor) throws Exception {
        System.out.println("Intercepted: " + constructor.getName());
    }
}

测试代码:

public static void main(String[] args) {
    new NoClassDefFoundError("should be intercepted!!!").toString();
    new Foo("oh").toString();
}

令人费解的是,将ElementMatchers.isSubTypeOf(LinkageError.class)替换为ElementMatchers.nameContains("Foo")给出了预期的结果,而Foo构造函数被拦截了。

NoClassDefFoundError 由 bootstrap 加载程序加载。它将无法看到您的拦截器 class 这就是它永远不会被触发的原因。

尝试使用 Advice class(作为访客)将字节码添加到匹配的 classes,这应该可以解决这个问题。