The findClass
method uses whatever mechanism it deems appropriate to load the class e.g., by reading a class file from the file system or from an HTTP server. It is then responsible for creating the
protection domain associated with the class and using the next method to create the Class
class object.
6.3.2.3 The defineClass methods
These methods all take an array of Java bytecodes and some information that specifies the permissions associated with the class represented by those bytecodes. They all return the
Class class object:
protected final Class defineClassString name, byte[] b, int off, int len throws ClassFormatError
protected final Class defineClassString name, byte[] b, int off, int len, ProtectionDomain protectionDomain throws ClassFormatError
protected final Class defineClassString name, byte[] b, int off, int len, CodeSource cs throws ClassFormatError
Create a class based on the bytecodes in the given array. The protection domain associated with the class varies based on which form is used:
In the first method, the class is assigned to the default protection domain. ◊
In the second method, the class is assigned to the given protection domain. ◊
In the third method, the protection domain is defined by the class loader based on the given code source.
◊
The third method in this list is available only within the SecureClassLoader
class and its subclasses including the
URLClassLoader class. When you use that method, the class loader will ask what
permissions are associated with a particular code source by calling this method: protected PermissionCollection getPermissionsCodeSource cs
Return the permissions that should be associated with the given code source. The default implementation of this method calls the
getPermissions method of the
Policy class.
Note that this gives you two effective ways in which to override the policy set up by policy files: by supplying your own
Policy class or by supplying your own secure class loader that overrides this method.
6.3.3 Responsibilities of the Class Loader
When you implement a class loader, you override some or all of the methods weve just listed. In sum, the class loader must perform the following steps:
The security manager is consulted to see if this program is allowed to access the class in question. If it is not, a security exception is thrown. This step is optional; it should be implemented at the beginning
of the loadClass
method. This corresponds to the use of the accessClassInPackage
permission. 1.
If the class loader has already loaded this class, it finds the previously defined class object and returns that object. This step is built into the
loadClass method.
2. Otherwise, the class loader consults its parent to see if the parent knows how to load the class. This is
a recursive operation, so the system class loader will always be asked first to load a class. This prevents programs from providing alternate definitions of classes in the core API but a clever class
loader can defeat that protection. This step is built into the loadClass
method. 3.
The security manager is consulted to see if this program is allowed to create the class in question. If it is not, a security exception is thrown. This step is optional; if implemented, it should appear at the
4. 104
beginning of the findClass
method. Note that this step should take place after the parent class loader is queried rather than at the beginning of the operation as is done with the access check. No
Sun−supplied class loader implements this step; it corresponds to the defineClassInPackage
permission. The class file is read into an array of bytes. The mechanism by which the class loader reads the file
and creates the byte array will vary depending on the class loader which, after all, is one of the points of having different class loaders. This occurs in the
findClass method.
5. The appropriate protection domain is created for the class. This can come from the default security
model i.e., from the policy files, and it can be augmented or even replaced by the class loader. Alternately, you can create a code source object and defer definition of the protection domain. This
occurs in the findClass
method. 6.
Within the findClass
method, a Class
object is constructed from the bytecodes by calling the
defineClass method. If you used a code source in step 6, the
getPermissions method will be called to find the permissions associated with the code source. The
defineClass method also ensures that the bytecodes are run through the bytecode verifier.
7.
Before the class can be used, it must be resolved −− which is to say that any classes that it immediately references must also be found by this class loader. The set of classes that are
immediately referenced contains any classes that the class extends as well as any classes used by the static initializers of the class. Note that classes that are used only as instance variables, method
parameters, or local variables are not normally loaded in this phase: they are loaded when the class actually references them although certain compiler optimizations may require that these classes be
loaded when the class is resolved. This step happens in the
loadClass method.
8.
In the next two sections, well see how this plays out in each of the class loader types. Note that we do not show how to subclass the
ClassLoader class directly: all class loaders should subclass the
SecureClassLoader class or its subclasses instead.
6.3.4 Using the URL Class Loader
If you want to use a custom class loader, the easiest route is to use the URL class loader. This limits the number of methods that you have to override.
To construct an instance of this class, use one of the following constructors: public URLClassLoaderURL urls[]
public URLClassLoaderURL urls[], ClassLoader parent Construct a class loader based on the given array of URLs. This class loader attempts to find a class
by searching each URL in the order in which it appears in the array. The parent of this class loader will be the class loader passed to the constructor or, if one is not
provided, the class loader of the class that is creating the URLClassLoader
object. An instance of the
URLClassLoader class may also be obtained via one of these methods:
public static URLClassLoader newInstanceURL[] urls public static URLClassLoader newInstanceURL[] urls, ClassLoader parent
Create and return a URL class loader. The difference between these methods and constructing a URL class loader directly is that the class loader returned from these methods will call the security
managers checkPackageAccess
method before it attempts to define a class. Only class loaders obtained this way will perform that optional step unless you write your own class loader to
perform that step. Chapter 6. Java Class Loaders