0

I am trying to inject a ByteBuddy agent at runtime, in a case where ByteBuddy was not present on the machine (and thus not in the classpath) when the JVM was launched. My first thought was to add the bytebuddy library jar files inside a directory present in the classpath, so that it gets loaded when I inject my agent, but I cannot find a way to retrieve the classpath of the running JVM. I was thus wondering if it is possible to use the Java Debug Interface to manually load the bytebuddy library jar files in the JVM just before injecting my agent.

I tried to adapt this code (using the JDI), which translate for the first two lines to :

ClassType jarFileClass = (ClassType) findClassRef("java.util.jar.JarFile");
Method jarFileInit = findOverloadRef("java.util.jar.JarFile", "<init>", "java.lang.String");
Method entries = findOverloadRef("java.util.jar.JarFile", "entries", "");
ArrayList<Value> argz = new ArrayList<Value>();
argz.add(vm.mirrorOf(path)); // path is the path to the bytebuddy library jar file, as a String
ObjectReference jarFile = jarFileClass.newInstance(ev.thread(), jarFileInit, argz, ObjectReference.INVOKE_SINGLE_THREADED);
ObjectReference x = jarFile.invokeMethod(ev.thread(), entries, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);

where findClassRef and findOverloadRef are methods of my own to respectively get a ReferenceType and a Method object. Sadly, I cannot get any further as the java.net.URL[] class is not loaded in the JVM, and thus I cannot get a ReferenceType for it.

How can I pursue my quest ?

AntoineG
  • 93
  • 7
  • Use the [Attach API](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.attach/com/sun/tools/attach/package-summary.html) to load an agent into an already running VM. If your agent is already running in the VM, use [`Instrumentation.appendToSystemClassLoaderSearch`](https://docs.oracle.com/en/java/javase/17/docs/api/java.instrument/java/lang/instrument/Instrumentation.html#appendToSystemClassLoaderSearch%28java.util.jar.JarFile%29). – Johannes Kuhn Dec 29 '21 at 14:46
  • Will the ByteBuddy agent run without the library jar loaded in the JVM ? – AntoineG Dec 29 '21 at 14:48
  • Then pack the agent with all required dependencies into one jar. – Johannes Kuhn Dec 29 '21 at 14:51
  • I'm going to try that, thank you ! – AntoineG Dec 29 '21 at 14:52

1 Answers1

2

Often, agents shade all of their dependencies into a single jar. This can still be problematic. Byte Buddy is a rather common dependency, it night already be on the class path but in a different version. To avoid this, many agents shade their dependency into a different namespace.

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192