I have been confused with UrlClassLoader delegation hierarchy and inheritance hierarchy.
I created class that extends UrlClassLoader and executed: childOfUrlClassLoader.getParent().getClass().getName()
which gave me:
sun.misc.Launcher$AppClassLoader
.
After this I pay a visit to mentioned above class (source)
249 static class AppClassLoader extends URLClassLoader {
//...
308 protected synchronized Class<?> loadClass(String name, boolean resolve)
309 throws ClassNotFoundException
310 {
311 // First, check if the class has already been loaded
312 Class c = findLoadedClass(name);
313 if (c == null) {
314 try {
315 if (parent != null) {
316 c = parent.loadClass(name, false);
317
// ...
329 return c;
330 }
Then I checked who is a parent of AppClassLoader. Expectedly I got sun.misc.Launcher$ExtClassLoader
and the parent of ExtClassLoader is null
.
I have a few questions:
1) Who loads my class since the code of AppClassLoader.loadClass
has line
294 return (super.loadClass(name, resolve));
It looks like loop, doesn't it?
2) Why doesn't ExtClassLoader have BootstrapClassLoader
as a parent, but has null
?
3) For which purpose AppClassLoader class extends UrlClassLoader?
Delegate-first model
The build-in java ClassLoaders follow a delegate-first model. This means that a ClassLoader will allow its parent to load a class before it tries to load it itself. The hierarchy of loaders has the bootstrap loader at the top, followed by the extension classloader, the application classloader. Under the application classloader can be found URLClassLoaders and any other loaders created by the application.
The bootstrap classloader can load files from rt.jar which contains the most essential java classes including those in the java.lang, java.io, java.util and java.net packages. The extension classloader loads classes from other jar files in the java installation. It is the application classloader which loads the classes found on the classpath and which is the current classloader when an application starts.
Loading in action
So what happens when an application wants to load a HashMap? The current classloader is asked to load the HashMap class. Before attempting anything, it asks its parent, the extension classloader to load the class. In turn the extension classloader delgates to the bootstrap classloader which finds the class in rt.jar and loads it.
If the class to be loaded is in the classpath, the request goes up to the bootstrap classloader as before to check rt.jar. The bootstrap loader fails to find the class, so the task is referred back to the extension classloader which searches the java installation for the class. When this fails the task reverts back to the application classloader which scans the classpath for the class.
The ClassLoader cache
In practice each classloader has a cache where classes already loaded are stored and the cache is searched before the delegation to the parent, but this does not alter the principle of delegating first.
This is where the cache is checked
Class c = findLoadedClass(name);
URLClassLoaders
A URLClassLoader created by an application will have the application ClassLoader as a parent. If it follows the delegate-first model, classes will be found in the classpath before the supplied URL.
The Questions
1) Who loads my class
I see slightly different code in your link
309 // First, check if the class has already been loaded
310 Class c = findLoadedClass(name);
311 if (c == null) {
312 try {
313 if (parent != null) {
314 c = parent.loadClass(name, false);
315 } else {
316 c = findBootstrapClass0(name);
317 }
318 } catch (ClassNotFoundException e) {
319 // If still not found, then invoke findClass in order
320 // to find the class.
321 c = findClass(name);
322 }
323 }
If a class is not loaded by the parent, it throws a ClassNotFoundException which is caught and allows the current ClassLoader to find the class
321 c = findClass(name);
2) Why doesn't ExtClassLoader have BootstrapClassLoader as a parent, but has null?
This is answered by the getClassLoader API
[getClassLoader()] returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader.
3) For which purpose AppClassLoader class extends UrlClassLoader?
Consider that the application classloader is not special in that it loads classes supplied by the user, not system classes. The classpath is effectively a list of URIs so a URLClassLoader is a suitable superclass.
References
There are many article on classloading including
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With