I'm trying to override the system's class loader using the flag -Djava.system.class.loader=MyLoader
. However, MyLoader
is still not being used when classes are loaded.
MyLoader
's code:
public class MyLoader extends ClassLoader {
public MyLoader(ClassLoader parent) {
super(S(parent));
}
private static ClassLoader S(ClassLoader cl) {
System.out.println("---MyLoader--- inside #constructor(" + cl + ")...");
return cl;
}
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
System.out.println("---MyLoader--- inside loadClass(" + name + ", " + resolve + ")...");
return super.loadClass(name, resolve);
}
}
This is the main code:
public class Main {
public static void main(final String args[]) throws Exception {
System.out.println("---Main--- first line");
System.out.println("---Main--- getSystemClassLoader(): " + ClassLoader.getSystemClassLoader());
System.out.println("---Main--- getSystemClassLoader()'s loader: " + ClassLoader.getSystemClassLoader().getClass().getClassLoader());
Call("javax.crypto.Cipher");
}
public static void Call(final String class_name) throws Exception {
System.out.println("---Main--- calling Class.forName(" + class_name + ")...");
Class.forName(class_name);
System.out.println("---Main--- call complete");
}
}
This is the output using the command java -Djava.system.class.loader=MyLoader -verbose -Xshare:off Main
(cf. Eclipse run config):
[Opened C:\Program Files\Java\jre7\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\Java\jre7\lib\rt.jar]
[Loaded java.io.Serializable from C:\Program
Files\Java\jre7\lib\rt.jar]
// etc etc... omitted since it's too long
[Loaded MyLoader from file:/C:/Documents%20and%20Settings/Owner/Desktop/Programs/Eclipse%20Workspace%202/Test93/bin/]
---MyLoader--- inside #constructor(sun.misc.Launcher$AppClassLoader@158046e)...
[Loaded sun.launcher.LauncherHelper from C:\Program Files\Java\jre7\lib\rt.jar]
[Loaded java.lang.StringCoding from C:\Program Files\Java\jre7\lib\rt.jar]
[Loaded java.lang.StringCoding$StringDecoder from C:\Program Files\Java\jre7\lib\rt.jar]
---MyLoader--- inside loadClass(Main, false)...
[Loaded Main from file:/C:/Documents%20and%20Settings/Owner/Desktop/Programs/Eclipse%20Workspace%202/Test93/bin/]
[Loaded java.lang.Void from C:\Program Files\Java\jre7\lib\rt.jar]
---Main--- first line
---Main--- getSystemClassLoader(): MyLoader@8697ce
---Main--- getSystemClassLoader()'s loader: sun.misc.Launcher$AppClassLoader@158046e
---Main--- calling Class.forName(javax.crypto.Cipher)...
[Opened C:\Program Files\Java\jre7\lib\jce.jar]
[Loaded javax.crypto.Cipher from C:\Program Files\Java\jre7\lib\jce.jar]
---Main--- call complete
As can be seen, even though Main
is loaded using MyLoader
, javax.crypto.Cipher
is not loaded using MyLoader
. The output shows that MyLoader.loadClass
is only called once.
Why is MyLoader.loadClass
not even called when javax.crypto.Cipher
is being loaded from jce.jar?