Java class loader
The Java class loader, part of the Java Runtime Environment, dynamically loads Java classes into the Java Virtual Machine. Usually classes are only loaded on demand. The virtual machine will only load the class files required for executing the program. The Java run time system does not need to know about files and file systems as this is delegated to the class loader.
A software library is a collection of related object code.
In the Java language, libraries are typically packaged in JAR files. Libraries can contain objects of different types. The most important type of object contained in a Jar file is a Java class. A class can be thought of as a named unit of code. The class loader is responsible for locating libraries, reading their contents, and loading the classes contained within the libraries. This loading is typically done "on demand", in that it does not occur until the class is called by the program. A class with a given name can only be loaded once by a given class loader.
Each Java class must be loaded by a class loader. Furthermore, Java programs may make use of external libraries or they may be composed, at least in part, of a number of libraries.
When the JVM is started, three class loaders are used:
- Bootstrap class loader
- Extensions class loader
- System class loader
/jre/lib directory. This class loader, which is part of the core JVM, is written in native code. The bootstrap class loader is not associated with any object. For instance, returns.The extensions class loader loads the code in the extensions directories.
The system class loader loads code found on
java.class.path, which maps to the CLASSPATH environment variable.User-defined class loaders
The Java class loader is written in Java. It is therefore possible to create a custom class loader without understanding the finer details of the Java Virtual Machine. Apart from the Bootstrap class loader, every Java class loader has a parent class loader. The parent class loader is defined when a new class loader is instantiated or set to the virtual machine's system default class loader.This makes it possible :
- to load or unload classes at runtime. This is an important feature for:
- * implementing scripting languages, such as Jython
- * using bean builders
- * allowing user-defined extensibility
- * allowing multiple namespaces to communicate. This is one of the foundations of CORBA / RMI protocols for example.
- to change the way the bytecode is loaded.
- to modify the loaded bytecode.
Class loaders in Jakarta EE
JAR hell
JAR hell is a term similar to DLL hell used to describe all the various ways in which the classloading process can end up not working. Three ways JAR hell can occur are:- Accidental presence of two different versions of a library installed on a system. This will not be considered an error by the system. Rather, the system will load classes from one or the other library. Adding the new library to the list of available libraries instead of replacing it may result in the application still behaving as though the old library is in use, which it may well be.
- Multiple libraries or applications require different versions of library foo. If versions of library foo use the same class names, there is no way to load the versions of library foo with the same class loader.
- The most complex JAR hell problems arise in circumstances that take advantage of the full complexity of the classloading system. A Java program is not required to use only a single "flat" class loader, but instead may be composed of several nested, cooperating class loaders. Classes loaded by different class loaders may interact in complex ways not fully comprehended by a developer, leading to errors or bugs that are difficult to analyze, explain, and resolve.
Java 9 introduced the Java Platform Module System in 2017. This specifies a distribution format for collections of Java code and associated resources. It also specifies a repository for storing these collections, or modules, and identifies how they can be discovered, loaded and checked for integrity. It includes features such as namespaces with the aim of fixing some of the shortcomings in the existing JAR format. The Java Platform Module System follows a different philosophy from the OSGi architecture that aims at providing modularity for the Java Runtime Environment in a backwards-compatible way that uses the default mechanism of loading classes that the JRE provides. However, since the Java Platform Module System does not offer the ability for controlled co-existence of libraries with different versions, it does not fully address the JAR hell problem.