Not able to intercept methods of java.net.HttpURLConnection class in Java 17
The provided code intercepts the connect method of the HttpURLConnection class in Java 8. However, when attempting to run the same code with Java 17, it results in an error provided below. please provide any solutions or suggestion.
CODE :
package com.bytebuddy.bytebuddydemo.test;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.loading.ClassInjector;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.matcher.ElementMatchers;
import java.io.File;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.util.Collections;
import java.util.concurrent.Callable;
public class Test {
public static void main(String[] args) throws Exception {
premain(null, ByteBuddyAgent.install());
HttpURLConnection urlConnection = (HttpURLConnection) new URL("http://www.google.com").openConnection();
System.out.println(urlConnection.getRequestMethod());
System.out.println(urlConnection.getResponseCode());
}
public static void premain(String arg, Instrumentation instrumentation) throws Exception {
File tempDirectory = Files.createTempDirectory("tmp").toFile();
ClassInjector.UsingInstrumentation
.of(tempDirectory, ClassInjector.UsingInstrumentation.Target.BOOTSTRAP, instrumentation)
.inject(Collections.singletonMap(new TypeDescription.ForLoadedType(MyInterceptor.class),
ClassFileLocator.ForClassLoader.read(MyInterceptor.class)));
new AgentBuilder.Default().ignore(ElementMatchers.nameStartsWith("net.bytebuddy."))
.with(new AgentBuilder.InjectionStrategy.UsingInstrumentation(instrumentation, tempDirectory))
.type(ElementMatchers.nameEndsWith(".HttpURLConnection"))
.transform((builder, typeDescription, classLoader, module) -> builder
.method(ElementMatchers.named("connect")).intercept(MethodDelegation.to(MyInterceptor.class)))
.installOn(instrumentation);
}
public static class MyInterceptor {
public static void intercept(@SuperCall Callable<?> zuper, @Origin Method method) throws Exception {
System.out.println("Intercepted!");
System.out.println("method :: !" + method);
zuper.call();
}
}
}
ERROR :
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.base/sun.net.www.protocol.http.Handler.openConnection(Handler.java:62)
at java.base/sun.net.www.protocol.http.Handler.openConnection(Handler.java:57)
at java.base/java.net.URL.openConnection(URL.java:1094)
at com.JavaAgent.Agent.Test.main(Test.java:26)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/sun.net.www.protocol.http.HttpURLConnection.
I assume this has to do with the module system preresolving names and not finding the new class. I would avoid auxiliary classes in such injection and rather use Advice to address such instrumentation.