Issue
I'm trying to time time it takes for the CompletableFuture
that is being returned by java.net.http.HttpClient#sendAsync
// 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");
}
}
I injected the ReponseConsumer
to the bootloader and I'm getting this error
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')
Just wondering how do i make the ReponseConsumer
class available in java.net.http
module
Solution
You are hitting the module system's boundaries and you have to add a read edge from your http client's module to the injected class. You can do so by adding a step in your code: assureReadEdgeTo
where you reference the target class or module.
Answered By - Rafael Winterhalter
Answer Checked By - Robin (JavaFixing Admin)