In Java, every class needs to be loaded before it can be used.
The class loader (which is part of JVM) is responsible for finding and loading the java classes.
A class loading is made once, at its first use.
Classes are uniquely identified by their fully qualified name and by the class loader which loaded them.
Popular exceptions caused by the class loading: ClassNotFoundException,
ClassCastException, NoClassDefFoundError.
- Bootstrap class loader
- Extensions class loader
- System class loader
<JAVA_HOME>/jre/lib
<JAVA_HOME>/jre/lib/ext
, or any
other directory specified by the java.ext.dirs
system property
java.class.path
(which by default is
the current directory; you can change the value by using the -classpath
or
-cp
command-line options, or setting the CLASSPATH
environment variable. The command-line options override the setting of the CLASSPATH
environment variable)
* Tomcat ignores this rule (see http://tomcat.apache.org/tomcat-7 .0-doc/class-loader-howto.html)
Each class loader has a "parent" class loader (besides the bootstrap class loader which is the root). When creating a class loader, if there isn't specified its parent, the system class loader will become its parent class loader.
When loading a class, theClassLoader
does the next actions:
ClassCastException
)
loadClass
method calls
findClass
method in order to find and load the class
Let's take some examples.
First example. Logging
Bootstrap class loader loads the java libraries (located in jre/lib
) =>java.util.logging.Logger
is loaded by Bootstrap class loader.
This logger
can use internationalization.
The resource bundle to be used is loaded by the System class loader.
The Bootstrap class
loader is not able to load the resource bundle, so the Logger
class needs
to use the class loader of the application; more precisely, the class loader of the current thread:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
A second example. Spring
Spring is used for managing beans. Let's say that Spring library is kept under tomcat/lib
.
Those classes are loaded by the common tomcat class loader.
For each web application in webapp
folder, a new class loader is created. This
class loader loads the classes in WEB-INF/classes
and
WEB-INF/lib
.
=> Normally, Spring cannot see those classes because they were loaded by a
different class loader.
In order to solve those issues, Java introduced the
Thread.currentThread().getContextClassLoader()
which can get the application's class loader and
use it for loading the classes in WEB-INF/classes
or
WEB-INF/lib
.
Java Language Specification, Execution chapter is one of the best materials to read for this subject: https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html