Step 4: Optionally call the checkPackageDefinition method

you must implement. Loading the class bytes is an operation left to the reader. The reason for providing your own class loader is that you want to read the class bytes in some special way; otherwise, youd use the URLClassLoader class. The code source is another matter: we must determine a URL and a set of certificates that should be associated with the class. In a signed jar file, the certificates are read from the jar file and the URL is the location of the jar file. In Chapter 12, well show how to get the certificates from a standard jar file and construct the appropriate code source. If your class definition isnt coming from a URL, then you must be a little creative. The simplest approach is to create an arbitrary URL. You could also use the methods we examine in Chapter 10, and load one or more certificates from the keystore; you would then use both items to construct the code source. The defineClass method will call back to the getPermissions method in order to complete the definition of the protection domain for this class. And thats why the URL used to construct the code source can be arbitrary: when you write the getPermissions method, just make sure that you understand what the URL actually is. In default usage, the URL would be used to find entries in the policy files, but since youre defining your own permissions anyway, the contents of the URL dont matter. What matters is that you follow a consistent convention between the definition of your getCodeSource and findClass methods. Hence, possible implementations of the getPermissions and getCodeSource methods are as follows: protected CodeSource getCodeSourceString name { try { return new CodeSourcenew URLfile, localhost, name, null; } catch MalformedURLException mue { mue.printStackTrace ; } return null; } protected PermissionCollection getPermissionsCodeSource codesource { PermissionCollection pc = new Permissions ; pc.addnew RuntimePermissionexitVM; return pc; } If youre reading the class bytes from, say, a database, it would be more useful if you could pass an arbitrary string to construct the code source. That doesnt work directly since the code source requires a URL but the file part of the URL can be any arbitrary string. In this case, we just use the class name. Note that the getPermissions method of the SecureClassLoader class does not add the additional permissions that the same method of the URLClassLoader class adds. As a result, we do not call the super.getPermissions method; instead, we construct a new permissions object directly.

6.3.6 Other Class Loaders

There are other class loaders within the Java API. Classes loaded by the primordial class loader do not have an associated protection domain alternately, we may say that they are associated with the system protection domain, which is why they have permission to perform any operation. Chapter 6. Java Class Loaders The appletviewer and Java Plug−in define their own class loader, which is an extension of the URL class loader. This class loader extends to classes loaded from a file URL the permissions to open a connection to and accept a connection from the localhost. Classes loaded from an HTTP URL have the same permissions as those granted in the URL class loader. The only other publicly−accessible class loader in the core API is the RMI class loader. There is a class called RMIClassLoader java.rmi.server.RMIClassLoader which, despite its name, is neither a class loader nor restricted to RMI. This class has a static method called loadClass which, like the loadClass method of the ClassLoader class, finds the named class and defines it. It uses an internal class loader to do this; the internal class loader happens to be a modification of the URLClassLoader class. The URL used by this class loader is specified by the java.rmi.server.codebase property; it uses the same permissions as a standard URL class loader. If the features of this class loader meet your requirements, you can use it in any program, regardless of whether your program uses RMI.

6.4 Miscellaneous Class Loading Topics

There are a few details about class loaders that we havent yet covered. These details are not directly related to the security aspects of the class loader, which is why weve saved them until now. If youre interested in the complete details of the class loader, well fill in the last few topics here.

6.4.1 Delegation

As weve mentioned, class loading follows a delegation model. This model permits a class loader to be instantiated with this constructor: protected ClassLoaderClassLoader parent Create a class loader that is associated with the given class loader. This class loader delegates all operations to the parent first: if the parent is able to fulfill the operation, this class loader takes no action. For example, when the class loader is asked to load a class via the loadClass method, it first calls the loadClass method of the parent. If that succeeds, the class returned by the delegate will ultimately be returned by this class. If that fails, the class loader then uses its original logic to complete its task, something like this: public Class loadClassString name { Class cl; cl = delegate.loadClassname; if cl = null return cl; else continue with the loadClass logic } You may retrieve the delegate associated with a class loader with the following method. public final ClassLoader getParent Return the class loader to which operations are being delegated. The class loader that exists at the root of the class loader hierarchy is retrieved via this method: public static ClassLoader getSystemClassLoader 110