 each class it loads, the JVM keeps track of which class loader -- whether primordial or object -- loaded the class. When a loaded class first refers to another class, the virtual machine requests the referenced class from the same class loader that originally loaded the referencing class. For example, if the virtual machine loads class
Volcano through a
particular class loader, it will attempt to load any classes
Volcano refers to through the same class loader. If
Volcano refers to a class named
perhaps by invoking a method in class
virtual machine will request
Lava from the class
loader that loaded
class returned by the class loader is dynamically linked with
Because the JVM takes this approach to loading classes, classes can by default only see other classes that were loaded by the same class loader. In this way, Java's architecture enables you to create multiple name-spaces inside a single Java application. A name-space is a set of unique names of the classes loaded by a particular class loader. For each class loader, the JVM maintains a name-space, which is populated by the names of all the classes that have been loaded through that class loader.
Once a JVM has loaded a class named
a particular name-space, for example, it is impossible to load a
different class named
Volcano into that same
name-space. You can load multiple
into a JVM, however, because you can create multiple name-spaces
inside a Java application. You can do so simply by creating
multiple class loaders. If you create three separate name-spaces
(one for each of the three class loaders) in a running Java
application, then, by loading one
Volcano class into
each name-space, your program could load three different
Volcano classes into your application.
A Java application can instantiate multiple class loader objects either from the same class or from multiple classes. It can, therefore, create as many (and as many different kinds of) class loader objects as it needs. Classes loaded by different class loaders are in different name-spaces and cannot gain access to each other unless the application explicitly allows it. When you write a Java application, you can segregate classes loaded from different sources into different name spaces. In this way, you can use Java's class loader architecture to control any interaction between code loaded from different sources. You can prevent hostile code from gaining access to and subverting friendly code.
Class loaders for
One example of dynamic extension with class loaders is the Web browser, which uses class loader objects to download the class files for an applet across a network. A Web browser fires off a Java application that installs a class loader object -- usually called an applet class loader -- that knows how to request class files from an HTTP server. Applets are an example of dynamic extension, because when the Java application starts, it doesn't know which class files the browser will ask it to download across the network. The class files to download are determined at run time, as the browser encounters pages that contain Java applets.
The Java application started by the Web browser usually creates a different applet class loader object for each location on the network from which it retrieves class files. As a result, class files from different sources are loaded by different class loader objects. This places them into different name-spaces inside the host Java application. Because the class files for applets from different sources are placed in separate name-spaces, the code of a malicious applet is restricted from interfering directly with class files downloaded from any other source.
Cooperation between class
Often, a class loader object relies on other class loaders -- at the very least, upon the primordial class loader -- to help it fulfill some of the class load requests that come its way. For example, imagine you write a Java application that installs a class loader whose particular manner of loading class files is achieved by downloading them across a network. Assume that during the course of runni