Tuesday, June 27, 2017

Java ClassLoader

@reference_1_stackoverflow
What is a Java ClassLoader?
@reference_2_oracle
Understanding Network Class Loaders
@reference_3_docs.oracle
Class ClassLoader

The bootstrap class loader loads the core Java libraries located in the <JAVA_HOME>/jre/lib directory. This class loader, which is part of the core JVM, is written in native code.
The extensions class loader loads the code in the extensions directories (<JAVA_HOME>/jre/lib/ext, or any other directory specified by the java.ext.dirs system property). It is implemented by the sun.misc.Launcher$ExtClassLoader class.
The system class loader loads code found on java.class.path, which maps to the CLASSPATH environment variable. This is implemented by the sun.misc.Launcher$AppClassLoader class.

@reference_4_wikipedia

Every class loaded in a Java application is identified by its fully qualified name (package name + class name), and the ClassLoader instance that loaded it. That means, that a class MyObject loaded by class loader A, is not the same class as the MyObject class loaded with class loader B.
MyObject object = (MyObject)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");
 
Notice how the MyObject class is referenced in the code, as the type of the object variable. This causes the MyObject class to be loaded by the same class loader that loaded the class this code is residing in.
If the myClassReloadingFactory object factory reloads the MyObject class using a different class loader than the class the above code resides in, you cannot cast the instance of the reloaded MyObject class to the MyObject type of the object variable. Since the two MyObject classes were loaded with different class loaders, the are regarded as different classes, even if they have the same fully qualified class name. Trying to cast an object of the one class to a reference of the other will result in a ClassCastException.
It is possible to work around this limitation but you will have to change your code in either of two ways:
  1. Use an interface as the variable type, and just reload the implementing class.
  2. Use a superclass as the variable type, and just reload a subclass.
Here are two coresponding code examples:
MyObjectInterface object = (MyObjectInterface)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");
MyObjectSuperclass object = (MyObjectSuperclass)
    myClassReloadingFactory.newInstance("com.jenkov.MyObject");
 
@reference_5_tutorials.jenkov.com
Java Reflection - Dynamic Class Loading and Reloading

No comments:

Post a Comment