bytebuddy 与 osgi 容器

bytebuddy with osgi container

尝试根据 bytebuddy 主页上的示例编写一个简单的 java 代理。我让代理工作,但是当我 运行 使用 OSGI 运行 时,它抛出 java.lang.NoClassDefFoundError。

有什么指点吗?

java.lang.ClassNotFoundException: com.foo.javaagent.TimingInterceptor cannot be found by ..

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


    public class TimerAgent {
        public static void premain(String arguments,
                                   Instrumentation instrumentation) {
            new AgentBuilder.Default()
                    .type(ElementMatchers.nameEndsWith("World"))
                    .transform((builder, type, classLoader, module) ->
                            builder.method(ElementMatchers.any())
                                    .intercept(MethodDelegation.to(TimingInterceptor.class))
                    ).installOn(instrumentation);
        }
    }

import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;


public class TimingInterceptor {
    @RuntimeType
    public static Object intercept(@Origin Method method,
                                   @SuperCall Callable<?> callable) throws Exception {
        long start = System.currentTimeMillis();
        try {
            return callable.call();
        } finally {
            System.out.println(method + " took " + (System.currentTimeMillis() - start));
        }
    }
}

TimingInterceptor class 由您的检测 classes 引用,因此必须可见。 OSGi 通过 class 加载程序隔离 classes,并且不会将系统 class 加载程序设置为加载代理的父级。为了避免这种情况,您需要将 classes 注入到 bootstrap class 加载程序中,使它们普遍可见。为此,请将拦截逻辑隔离在一个单独的 jar 中,并通过用于安装代理的 Instrumentation 实例将此 jar 附加到 bootstrap class 加载程序搜索路径。您需要在安装代理之前执行此操作。