Bytebuddy:如何注入java.net.HttpClient#sendAsync可以读取的类



我正在计算java.net.http.HttpClient#sendAsync返回的CompletableFuture所需的时间

// premain
public static void premain(String arguments, Instrumentation instrumentation) {
// ...inject helper class to bootloader
new AgentBuilder.Default()
.ignore(ElementMatchers.none())
.with(Listener.StreamWriting.toSystemOut().withErrorsOnly())
.type(hasSuperType(named("java.net.http.HttpClient")))
.transform((builder, typeDescription, classLoader,
module, protectionDomain) -> {
return builder
.visit(Advice.to(SendAsyncAdvice.class)
.on(hasMethodName("async")));
})
.asTerminalTransformation()
.installOn(instrumentation);
}
class SendAsyncAdvice {
@Advice.OnMethodExit()
public static void exit(
@Advice.Return(readOnly = false) CompletableFuture<HttpResponse<?>> future) {
future = future.whenComplete(new ResponseConsumer());
}
}
class ReponseConsumer implements BiConsumer<HttpResponse<?>, Throwable> {
@Override
public void accept(HttpResponse<?> arg0, Throwable arg1) {
System.out.println("HELLO");
}
}

我将ReponseConsumer注入到引导程序中,我得到了这个错误

Exception in thread "main" java.lang.IllegalAccessError: 
failed to access class io.hello.agent.SendAsyncAdvice 
from class jdk.internal.net.http.HttpClientImpl
(io.hello.agent.SendAsyncAdvice is in unnamed module of loader 
'bootstrap'; jdk.internal.net.http.HttpClientImpl 
is in module java.net.http of loader 'platform')

只是想知道如何在java.net.http模块中提供ReponseConsumer

您正在触及模块系统的边界,必须将http客户端模块的读取边缘添加到注入的类中。您可以通过在代码中添加一个步骤来实现这一点:assureReadEdgeTo,在这里您可以引用目标类或模块。

最新更新