微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用bytebuddy从拦截方法调用lambda会引发java.lang.NoClassDefFoundError:

如何解决使用bytebuddy从拦截方法调用lambda会引发java.lang.NoClassDefFoundError:

我正在尝试使用ByteBuddy和Java代理进行一些检测。在其中一个步骤中,我想捕获stacktrace并使用我关心的调用对其进行过滤。让我们想象一个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表达式。因此,我的问题是:我该怎么做才能确保已加载?我当时正在考虑创建一个类,并通过ByteBuddy将其与所有实用程序一起加载。有没有更优雅的方式?

解决方法

Byte Buddy无法将lambda表达式从advice方法复制到目标方法。从技术上讲,Lambda只是在定义该类的类中使用私有方法,而这些方法将对目标类不可用。

使用常规迭代来避免此问题。另外,您需要在单个类中实现表达式,然后使用ClassInjector将这些类注入目标类加载器。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。