In the parent delegation model for loading classes, I know that loadclass() is invoked on the parent, all the way to the top of the class-loader hierarchy (assuming the class is not loaded). At which point the topmost parent classloader's findClass is invoked. If this class is not found, how is the control transferred to the next classloader's findClass method ?
The findClass(String) will be invoked by the loadClass(String) method of the classloader. It's default implementation throws a ClassNotFoundException and is intended to be overridden by classloaders.
The loadClass(String) method will call the following methods in that order
- First it tries to find if the class already loaded:
findLoadedClass(String)
- Then if not found it calls the parent' classloaders
loadClass(String)
method. - If not found, it will call the
findClass(String)
method (custom loading)
So all a custom classloader has to do is override the findClass(String)
method to load classes in a custom way. This will ensure the proper delegation in classloading. Check the links (javadoc), it explains what steps are taken and how the findClass(String)
is called from loadClass(String)
So the classloading takes place in following order (example) ClassLoader A with parent B (only explaining the findClass and loadClass)
A.loadClass()
|
(not-found?) (by findLoadedClass)
|
B.loadClass()
|
(not found?) (by findLoadedClass)
|
systemclassloader.loadClass() (Bs parent, also can be
| called classpath classloader)
|
(not found?) (by findLoadedClass)
|
bootstrap classloader.loadClass() (the bootstrap classloader,
| this has no parent)
|
(not found?)
|
systemclassloader.findClass() (on system classloader,
| will try to "find" class in "classpath")
|
(not found?)
|
B.findClass()
|
(not found?)
|
A.findClass()
|
(not found?)
|
ClassNotFoundException
At any given time if the class is found (eigther by findClass or findLoadedClass), that class is returned.
findLoadedClass
? –
Alberthaalberti The above explanation is comprehensive and excellent. A more straightforward way to understand the principle of delegation class loading to is read the source code. Any way, the source code is not complex at all.
400 protected Class<?> loadClass(String name, boolean resolve)
401 throws ClassNotFoundException
402 {
403 synchronized (getClassLoadingLock(name)) {
404 // First, check if the class has already been loaded
405 Class c = findLoadedClass(name);
406 if (c == null) {
407 long t0 = System.nanoTime();
408 try {
409 if (parent != null) {
410 c = parent.loadClass(name, false);
411 } else {
412 c = findBootstrapClassOrNull(name);
413 }
414 } catch (ClassNotFoundException e) {
415 // ClassNotFoundException thrown if class not found
416 // from the non-null parent class loader
417 }
418
419 if (c == null) {
420 // If still not found, then invoke findClass in order
421 // to find the class.
422 long t1 = System.nanoTime();
423 c = findClass(name);
424
425 // this is the defining class loader; record the stats
426 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
427 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
428 sun.misc.PerfCounter.getFindClasses().increment();
429 }
430 }
431 if (resolve) {
432 resolveClass(c);
433 }
434 return c;
435 }
436 }
© 2022 - 2024 — McMap. All rights reserved.