I have a java-agent which relies on some dependency libraries. We have a custom classloader which does not do globbing and provides deterministic class loading, and is specified via the -Djava.system.class.loader=. However it seems that the java-agent classes are still getting loaded via the AppClassLoader, leading to some ClassNotFoundExceptions. After having wasted a couple of hours on this, I came across this JDK bug which outlines this exact issue and is closed now, but the fix has been made only to JDK 9+.
I was wondering is there a way in Java <=8 to enforce the java-agent classes to be loaded by the classloader specified.
The custom class loader looks something like this,
public class CustomClassloader extends URLClassLoader{
public CustomClassloader(ClassLoader parent) throws Exception {
//getJarPaths has the path of the java-agent jar as well as
//all dependency jar it needs.
super(getJarPaths(), parent);
}
private static URL[] getJarPaths() throws Exception {
//custom implementation
}
public void appendToClassPathForInstrumentation(String path) throws MalformedURLException {
assert(Thread.holdsLock(this));
super.addURL(Paths.get(path).toUri().toURL());
}
}
The above classloader works perfectly with JDK9+, and the javaagent is actually loaded by the custom classloader.