
One of the main features of the Java platform is the dynamic class loading model, which allows you to load executable code into the JRE without reloading the main application. This feature is widely used in application servers that have recently received high popularity.
The article describes the basic concepts, aspects and principles of the dynamic code loading model. The next article will discuss the implementation of a native class loader, as the main mechanism of an application with a plug-in architecture.
')
Introduction
Any class (an instance of the java.lang.Class class in the environment and the .class file in the file system) used in the execution environment was somehow loaded by some loader in Java. In order to get the loader that loaded class A, you need to use the method A.class.getClassLoader ().
Classes are loaded as needed, with a few exceptions. Some base classes from rt.jar (java.lang. * In particular) are loaded when the application starts. Extension classes ($ JAVA_HOME / lib / ext), user-defined and most system classes are loaded as they are used.
Types of loaders
There are 3 types of loaders in Java. This is the basic boot loader (bootstrap), system loader (System Classloader), extension loader (Extension Classloader).
Bootstrap - implemented at the JVM level and has no feedback from the execution environment. This loader loads classes from the $ JAVA_HOME / lib directory. Those. everyone's favorite rt.jar is loaded by the basic loader. Therefore, an attempt to get the loader from the java. * Classes always ends in a null. This is due to the fact that all base classes are loaded with a basic loader, which is not accessible from the managed environment.
You can control the loading of base classes with the -Xbootclasspath switch, which allows you to override sets of base classes.
System Classloader is a system loader implemented already at the JRE level. In Sun, JRE is the class sun.misc.Launcher $ AppClassLoader. This loader loads classes whose paths are specified in the CLASSPATH environment variable.
You can control the loading of system classes using the -classpath switch or the java.class.path system option.
Extension Classloader - extension loader. This loader loads classes from the $ JAVA_HOME / lib / ext directory. In Sun, JRE is the class sun.misc.Launcher $ ExtClassLoader.
You can control the loading of extensions using the java.ext.dirs system option.
Concepts
A distinction is made between the current loader (Current Classloader) and the context loader (Context Classloader).
Current Classloader is a class loader whose code is currently being executed. The current loader is used by default to load classes during execution. In particular, when using the Class.forName ("") / ClassLoader.loadClass ("") method or on any class declaration that was not previously loaded.
Context Classloader - current context context loader. You can get and install this loader using the methods Thread.getContextClassLoader () / Thread.setContextClassLoader (). The context loader is automatically installed for each new thread. At the same time, the parent stream loader is used.
Load Delegation Model
Starting with the Java 2 Platform, Standard Edition, v1.2 class loaders form a hierarchy. The root is the base (it has no ancestor). All other loaders instantiate the link to the parent loader when initialized. This hierarchy is required for the load delegation model. In general, the hierarchy is as follows.

The right to load a class is recursively delegated from the lowest loader in the hierarchy to the highest one. This approach allows classes to be loaded by the loader that is as close as possible to the base one. So the maximum area of visibility of classes is reached. By scope is meant the following. Each loader keeps track of the classes that it has loaded. The set of these classes is called the scope.

Consider the boot process in more detail. Let the manifest variable of the custom class Student meet in the execution systems.
1) The system loader will attempt to search the Student class in the cache.
_1.1) If the class is found, the download is finished.
_1.2) If the class is not found, the load is delegated to the extension loader.
2) The extension loader will try to search the student class in the cache.
_2.1) If the class is found, the download is finished.
_2.2) If the class is not found, the load is delegated to the base loader.
3) The basic loader will try to search the student class in the cache.
_3.1) If the class is found, the download is finished.
_3.2) If the class is not found, the base loader will try to load it.
__3.2.1) If the download is successful, it is finished;)
__3.2.2) Otherwise, the control is committed to the extension loader.
_3.3) The extension loader is trying to load a class.
__3.3.1) If the download is successful, it is finished;)
__3.3.2) Otherwise, control is handed over to the system loader.
_3.4) The system loader is trying to load a class.
__3.4.1) If the download is successful, it is finished;)
__3.4.2) Otherwise, a java.lang.ClassNotFoundException exception is generated.
If there are custom loaders on the system, they should
a) extend the java.lang.ClassLoader class;
b) support the dynamic loading model.
Inside
Let's start the simplest application with the -verbose: class key.
public class A { }
public class B extends A { }
public class C extends B { }
public class Main {
public static void main( String args[]) {
C c = new C();
B b = new B();
A a = new A();
}
}
* This source code was highlighted with Source Code Highlighter .
The output shows that the classes were loaded in the wrong order in which they were used. This is due to inheritance.
[Loaded Main from file: / C: / devel / CL / bin /]
[Loaded A from file: / C: / devel / CL / bin /]
[Loaded B from file: / C: / devel / CL / bin /]
[Loaded C from file: / C: / devel / CL / bin /]
Conclusion
The next article will be more interesting;)