ng the Java application, a request is made of your class loader to load a class named
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
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
class could then play a role in the application's future course
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
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
class back to your class loader.
The primordial class loader most likely didn't have to
String at this point because, given
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
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
references a class named
Class loaders in the
In Java's sandbox, the class loader architecture is the first line of defense against malicious code. It is the class loader, after all, that brings code into the JVM -- code that could be hostile.
The class loader architecture contributes to Java's sandbox in two ways:
The class loader architecture guards the borders of the trusted class libraries by making sure untrusted classes can't pretend to be trusted. If a malicious class could successfully trick the JVM into believing it was a trusted class from the Java API, that malicious class potentially could break through the sandbox barrier. By preventing untrusted classes from impersonating trusted classes, the class loader architecture blocks one potential approach to compromising the security of the Java runtime.
The class loader architecture prevents malicious code from interfering with benevolent code by providing protected name-spaces for classes loaded by different class loaders. As mentioned above, name-space is a set of unique names for loaded classes that is maintained by the JVM.
Name-spaces contribute to security because you can, in effect, place a shield between classes loaded into different name-spaces. Inside the JVM, classes in the same name-space can interact with one another directly. Classes in different name-spaces, however, can't even detect each other's presence unless you explicitly provide a mechanism that allows the classes to interact. If a malicious class, once loaded, had guaranteed access to every other class currently loaded by the virtual machine, that class potentially could learn things it shouldn't know, or it could interfere with the proper execution of your program.
Creating a secure
When you write an application that uses class loaders, you create an environment in which the dynamically loaded code runs. If you want the environment to be free of security holes, you must follow certain rules when you write your application and class loaders. In general, you will want to write your application so that malicious code will be shielded from benevolent code. Also, you will want to write class loaders such that they protect the borders of trusted class libraries, such as those of the Java API.
Name-spaces and code
