In this article we will give a very simple explanation of what ClassLoaders do in Java. This article starts a series, and in following articles we will show some ways of “replacing” the default class loader and what interesting things come out of it.
In contrary to such languages like C++ or Fortran where source code is compiled directly to machine’s native code, Java’s source code is compiled to platform-independent Java bytecode. Normally Java Virtual Machine loads this bytecode for every required class from .class files from the local file system. Java gives us however a possibility to greatly influence the way bytecode is load – customized class loaders.
Every request for a class from inside the code goes through a chain of default class loaders. Normally there are three of them:
- Bootstrap class loader – loads core Java classes like java.lang.System orjava.lang.Integer
- Extensions class loader – loads classes from <JAVA_HOME>/lib/ext
- System class loader – loads classes from the current CLASSPATH
“Chaining” of class loaders means, that every class loader has a parent class loader, and in most cases it asks its parent to load a requested class before trying to resolve it on its own. If the parent can not find the class, the class loader itself tries to load the class. A rough view of class loading is represented on the image below:
Bootstrap class loader is pretty special, in that it is implemented in native code. All other class loaders are written in Java (apart from some native methods) and extend thejava.lang.ClassLoader class. We could get the class loader which was used to load any particular class with class.getClassLoader() method:
public class ShowClassLoaders { /** * This main method shows which class * loaders are used for loading classes * like Integer, BlowfishCipher (lib/ext) * and ShowClassLoaders. */ public static void main(String[] args) { System.out.println("class loader for Integer: " + Integer.class.getClassLoader()); System.out.println("class loader for BlowfishCipher: " + com.sun.crypto.provider .BlowfishCipher.class.getClassLoader()); System.out.println("class loader for this class: " + ShowClassLoaders.class.getClassLoader()); } }
When we run this program, we will see the following output:
class loader for Integer: null class loader for BlowfishCipher: sun.misc.Launcher$ExtClassLoader@9cab16 class loader for this class: <a href="mailto:sun.misc.Launcher$AppClassLoader@d9f9c3">sun.misc.Launcher$AppClassLoader@d9f9c3</a>
java.lang.Integer was loaded using the bootstrap class loader. In most implementations getClassLoader() method returns null for the bootstrap class loader. com.sun.crypto.provider.BlowfishCipher class is stored inside the <JAVA_HOME>/lib/ext/sunjce_provider.jar so it was loaded with the extensions class loader. Classes implemented by us, like the class with the main method, was loaded by system class loader.
Java ClassLoader is a powerful tool that can be used in a various of ways to extend the possibilities of Java applications. One of the most well-known usages of custom class loaders are Java Applets, where a class loader is used to dynamically download code from the webpage. Customized ClassLoaders are also the base element of Java Application Servers and Web Containers. ClassLoaders are one of things that make the Java platform so extensible and flexible.