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 加载程序搜索路径。您需要在安装代理之前执行此操作。
尝试根据 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 加载程序搜索路径。您需要在安装代理之前执行此操作。