3.2. Anatomy of a Class Loader
When the Java virtual machine needs access to a particular class, it is up to a class loader to provide the class. The class loader goes through the following steps to load and define a class:
Step 5 of this process varies depending on the policy of the particular class loader--the data for the class may be read from the network or the filesystem (or from any other location, such as a database). The other steps of this process will remain fixed for a well-defined class loader.
There are a number of class loaders that are used in Java programs, described in the following sections.
3.2.1. The Internal Class Loader
All Java programs must have the capability of loading certain classes--the Java API classes and any others located in the user's CLASSPATH. Some of these classes are bootstrapped into the virtual machine. The first thing the virtual machine typically does is load the Java API class files (the rt.jar file) for future use.
The internal class loader uses the native operating system's file access methods to open and read the class files into byte arrays. When one of these classes contains a reference to another class, the internal class loader is again consulted to load the referenced class.
Unlike other class loaders we'll explore, the internal class loader cannot be overridden. Most of the internal class loader, in fact, is written in native code so that it can be accessed directly by the virtual machine (a requirement for the virtual machine to be able to bootstrap the API classes).
The internal class loader is often referred to as the default class loader or the primordial class loader. Due to some details of the Class class, we often speak of classes that are loaded by the internal class loader as having no class loader at all (and as a result, the internal class loader is sometimes called the null class loader).
There is a significant change in the use of the primordial class loader between Java 1.1 and 1.2. In 1.1, the primordial class loader was used to load all classes on the CLASSPATH. In 1.2, the primordial class loader is used only to load the Java API class files; the virtual machine constructs an instance of the URLClassLoader class to load the classes from the CLASSPATH.
3.2.2. The Applet Class Loader
An applet needs the ability to load classes via HTTP from the network. Hence, applet class loaders typically use the URL class to read in the data for a class file from the applet's CODEBASE host.
There is no standard applet class loader in the Java API--each Java browser is responsible for implementing its own class loader. In practice, the class loaders of various browsers are indistinguishable (and are usually based on the reference class loader implemented in Sun's appletviewer), but a Java programmer cannot simply instantiate an applet class loader in a platform-independent way.
3.2.3. The RMI Class Loader
Beginning with JDK 1.1, the Java API includes an RMI class loader that can be used by any application. Despite its name, the RMI class loader needn't be used in an RMI application, and it is not truly a class loader--that is, it does not extend the ClassLoader class. In function, the RMIClassLoader class (java.rmi.server.RMIClassLoader) is very similar to the applet class loader--it uses the HTTP protocol to load the desired class file from a remote machine and then defines the class from the data in that file.
The RMI class loader cannot be instantiated directly; you must use one of its static methods to load a class. Once an initial class is loaded by the RMI class loader, any classes it references will also be loaded by the RMI class loader. In addition, the RMI class loader can only load classes from the URL specified by the java.rmi.server.codebase property, so it is not a generic solution to all applications where a class loader might be used.
If you are loading individual, unsigned classes (i.e., classes that are not in a JAR file) from a single URL (i.e., a single directory, whether a file-based or an HTTP-based URL), using the RMI class loader is the simplest option for Java 1.1 applications. For Java 1.2 applications, you can use the RMI class loader for this purpose, or you can use the URL class loader; the URL class loader will offer you more flexibility.
3.2.4. The Secure Class Loader
Beginning with Java 1.2, the Java API includes a class loader in the java.security package called SecureClassLoader. This class has a protected constructor, so its real use is to provide the basis for the development of other class loaders. The distinguishing feature of the secure class loader is that it associates a protection domain with each class that it loads. Protection domains form the basis of the operation of the access controller; we'll see more about them in Chapter 5, "The Access Controller". For now, just accept the fact that if you want to use the access controller to establish your security policy, you'll need to use a class loader that extends the SecureClassLoader class.
3.2.5. The URL Class Loader
Also beginning with Java 1.2, the Java API includes a general-purpose class loader that can load classes from a set of URLs: the URLClassLoader class (java.net.URLClassLoader). This class is public and fully implemented, so for 1.2-based applications, it provides a truly useful, general purpose class loader:
An instance of the URLClassLoader class is created via one of these constructors:
An instance of the URLClassLoader class may also be obtained via one of these methods:
We can construct a URL class loader like this:
URL urls = new URL; urls = new URL("http://piccolo.East/~sdo/"); urls = new URL("file:/home/classes/LocalClasses.jar"); URLClassLoader ucl = new URLClassLoader(urls, parent);
When we use this class loader to load the class com.sdo.Car, the class loader first attempts to load it via the URL http://piccolo.East/~sdo/com/sdo/Car.class; if that fails, it looks for the class in the LocalClasses.jar file.
It should come as no surprise that this class is the basis for running the Launcher. In that case, the array of URLs is created based on the list of URLs that make up the CLASSPATH (but not including the core Java API classes).
3.2.6. Choosing the Right Class Loader
With all these class loaders to choose from, which is the better choice: an existing class loader or your own custom class loader? The answer depends upon your needs. It is better not to write your own class loader if an existing one can fit your needs, but that's not always possible. Here are some guidelines:
Copyright © 2001 O'Reilly & Associates. All rights reserved.