|
|
|
Advertisement
|
Class loaders and name-spaces
For 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
Lava, perhaps by invoking a method in class
Lava, the virtual machine will request Lava
from the class loader that loaded Volcano. The
Lava class returned by the class loader is dynamically
linked with class Volcano.
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 Volcano into 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 Volcano classes 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 applets
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 loaders
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 running the Java application,
a request is made of your class loader to load a class named
Volcano.
One way you could write the class loader is to have it first ask the
primordial class loader to find and load the class from its trusted
repository. In this case, since Volcano is not a part of
the Java API, assume the primordial class loader can't find a class
named Volcano. When the primordial class loader responds
that it can't load the class, your class loader could then attempt to
load the Volcano class in its custom manner, by
downloading it across the network. Assuming your class loader was able
to download class Volcano, that Volcano class
could then play a role in the application's future course of
execution.
To continue with the same example, assume that some time later a method
of class Volcano is invoked for the first time, and that
the method references class String from the Java API.
Because it is the first time the reference is used by the running
program, the virtual machine asks your class loader (the one that
loaded Volcano) to load String. As before,
your class loader first passes the request to the primordial class
loader, but in this case, the primordial class loader is able to return
a String class back to your class loader.
The primordial class loader most likely didn't have to actually load
String at this point because, given that
String is such a fundamental class in Java programs, it
was almost certainly used before and therefore already loaded. Most
likely, the primordial class loader just returned the
String class that it had previously loaded from the
trusted repository.
Since the primordial class loader was able to find the class, your
class loader doesn't attempt to download it across the network; it
merely passes to the virtual machine the String class
returned by the primordial class loader. From that point forward, the
virtual machine uses that String class whenever class
Volcano references a class named String.
|
Sponsored Links
|