calling lambda from an intercept method with bytebuddy raises java.lang.NoClassDefFoundError:
calling lambda from an intercept method with bytebuddy raises java.lang.NoClassDefFoundError:
我正在尝试使用 ByteBuddy 和 java 代理进行一些检测。在其中一个步骤中,我想捕获堆栈跟踪并使用我关心的调用对其进行过滤。让我们想象一个 premain 函数看起来像这样:
public class SeleniumReporter {
public static void premain(final String agentArgs, final Instrumentation inst) {
new AgentBuilder.Default()
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
.type(named("org.openqa.selenium.remote.RemoteWebDriver"))
.transform((builder, type, classLoader, module) -> builder
.method(nameStartsWith("findElement")
.and(takesArguments(By.class).or(takesArguments(String.class, String.class)))
.and(isPublic())
)
.intercept(Advice.to(FindElementInterceptor.class))
)
.installOn(inst);
}
}
拦截器采用这种形式:
public class FindElementInterceptor {
@Advice.OnMethodExit
public static void log(@Advice.This RemoteWebDriver driver, @Advice.Origin String method, @Advice.AllArguments Object[] args) {
/*
... Some extra code
*/
final String stackTrace = Arrays.stream(Thread.currentThread().getStackTrace())
.map(t -> String.format("%s:%s", t.getClassName(), t.getMethodName()))
.filter(s -> !s.startsWith("org.codehaus.plexus."))
.filter(s -> !s.startsWith("org.apache.maven."))
.collect(Collectors.joining(";"));
System.out.println(stackTrace);
}
}
运行 该代码将抛出 java.lang.NoClassDefFoundError 因为 lambda 表达式未加载。因此,我的问题是:我该怎么做才能确保已加载?我正在考虑创建一个 class 并使用所有实用程序通过 ByteBuddy 加载它。有没有更优雅的方式?
字节好友无法将 lambda 表达式从建议方法复制到目标方法。从技术上讲,Lambda 只是定义它的 class 中的私有方法,目标 class.
将不可用
改为使用常规迭代来避免此问题。或者,您需要在单个 classes 中实现表达式,并使用 ClassInjector
.
将这些 classes 注入到目标 class 加载器中
我正在尝试使用 ByteBuddy 和 java 代理进行一些检测。在其中一个步骤中,我想捕获堆栈跟踪并使用我关心的调用对其进行过滤。让我们想象一个 premain 函数看起来像这样:
public class SeleniumReporter {
public static void premain(final String agentArgs, final Instrumentation inst) {
new AgentBuilder.Default()
.with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
.type(named("org.openqa.selenium.remote.RemoteWebDriver"))
.transform((builder, type, classLoader, module) -> builder
.method(nameStartsWith("findElement")
.and(takesArguments(By.class).or(takesArguments(String.class, String.class)))
.and(isPublic())
)
.intercept(Advice.to(FindElementInterceptor.class))
)
.installOn(inst);
}
}
拦截器采用这种形式:
public class FindElementInterceptor {
@Advice.OnMethodExit
public static void log(@Advice.This RemoteWebDriver driver, @Advice.Origin String method, @Advice.AllArguments Object[] args) {
/*
... Some extra code
*/
final String stackTrace = Arrays.stream(Thread.currentThread().getStackTrace())
.map(t -> String.format("%s:%s", t.getClassName(), t.getMethodName()))
.filter(s -> !s.startsWith("org.codehaus.plexus."))
.filter(s -> !s.startsWith("org.apache.maven."))
.collect(Collectors.joining(";"));
System.out.println(stackTrace);
}
}
运行 该代码将抛出 java.lang.NoClassDefFoundError 因为 lambda 表达式未加载。因此,我的问题是:我该怎么做才能确保已加载?我正在考虑创建一个 class 并使用所有实用程序通过 ByteBuddy 加载它。有没有更优雅的方式?
字节好友无法将 lambda 表达式从建议方法复制到目标方法。从技术上讲,Lambda 只是定义它的 class 中的私有方法,目标 class.
将不可用改为使用常规迭代来避免此问题。或者,您需要在单个 classes 中实现表达式,并使用 ClassInjector
.