The Artima Developer Community
Sponsored Link

Object Mobility in the Jini Environment
Simplify the Installation and Configuration of Jini Applications
by Frank Sommers
First Published in JavaWorld, January 2001

<<  Page 2 of 9  >>


A Class Loader Refresher

The Java Virtual Machine's (JVM) job is to execute Java bytecode. Bytecode is stored in Java classfiles, which are loaded into the JVM via a class loader. Loading a class means locating a classfile that contains the desired type, based on the type's name, and then creating the class from that file (see the Java Virtual Machine Specification, Chapter 5). Once a class is loaded into a VM, it is linked into the VM's execution state, which means that it becomes part of the program's execution. Finally, the VM initializes the class by calling a special initialization method, which essentially corresponds to static initialization of the class.

When a JVM starts up, it loads a class using a bootstrap class loader. This first class must have a public static void main(String[] argv) method. The VM calls that method after initializing the class, and then starts executing code specified in the main() method.

Code in the main method will reference classes not yet loaded into the VM. When the VM encounters such a reference, it asks its class loader to load, link, and initialize this class as well. The class loader uses a codebase to try to locate the requested classfile. The codebase is the location where the class loader searches for classfiles.

If there were only a bootstrap class loader, this process would not be very powerful, since all classes would have to be installed at a predetermined location. Fortunately, the JVM's class loader architecture is modular. In addition to its built-in class loader, a VM allows any number of user-defined class loaders.

Since the second version of the JVM specification (available since Java 1.2), class loaders have formed a hierarchical relationship. Every class loader has a parent class loader. The bootstrap class loader is the the root node of the tree; the VM supplies it. When a class references a type not yet loaded into the VM, it first asks its class loader's parent to load it. This parent class loader, in turn, will delegate the class loading to its parent, and so forth, until the delegation reaches the ultimate parent, typically the bootstrap class loader. If the bootstrap class loader can find the class, it will load and create it, and pass a reference to that class back to its child class loader, which in turn will pass it back to its child, and so on, all the way to the class loader that requested the class. If the bootstrap class loader cannot locate the class, it will ask its child to locate it. If that child cannot load it, it will, in turn, ask its child. Only when none of its parents are able to return a reference to a loaded class will the original class loader try to load the class. If, at that point, the class is still not found, a ClassNotFoundException is thrown. This is the parent-delegation principle of class loading, which was first introduced in the 1.2 version of the JVM. (See Java Virtual Machine Specification, Section 5.3.2.)

In Java 2, the bootstrap class loader considers a CLASSPATH environment variable to determine its codebase. By default, the Java Core class library, supplied by the Java Runtime Environment (JRE), is also a part of that codebase. A different class loader, the Extension class loader, loads classes that are part of the Java Standard Extensions. Every other class is loaded by some other, user-defined, class loader.

Figure 1. The JVM's hierarchical class loader architecture

User-defined class loaders are specified in the Java programming language, and are created with code such as the following:

ClassLoader myClassLoader = new MyClassLoader(parentClassLoader);

Here parentClassLoader is a reference to a parent class loader instance. If a null is passed into the constructor, the bootstrap class loader will be the parent.

Here's an important method that the ClassLoader class specifies:

Class findClass(String className) {...}

Overriding this method can customize the way the specified class is located by the VM. If the class cannot be found, the VM throws a ClassNotFoundException. This method is typically called automatically by a ClassLoader's method:

Class loadClass(String className)

loadClass() does the following:

  1. It calls findLoadedClass(className), which tells it if the specified class has already been loaded
  2. It calls loadClass(className) on the parent class loader, and, ultimately, on the bootstrap class loader
  3. It calls findClass(className)

It's important to remember that, based on the parent-delegation principle, the search for the class is ultimately delegated to the bootstrap class loader first, and then proceeds down the succession of child class loaders. If any class loader in this chain finds the classfile in its codebase, the VM will load, link, and initialize that class, and will not search any further.

<<  Page 2 of 9  >>

Sponsored Links

Copyright © 1996-2018 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use