Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## net.jini.loader.pref
Class PreferredClassLoader

    java.lang.Object
      java.lang.ClassLoader
          java.security.SecureClassLoader
              java.net.URLClassLoader
                  net.jini.loader.pref.PreferredClassLoader

All Implemented Interfaces:
  ClassAnnotation

public class PreferredClassLoader
extends URLClassLoader
implements ClassAnnotation

A class loader that supports preferred classes.

A preferred class is a class that is to be loaded by a class loader without the loader delegating to its parent class loader first. Resources may also be preferred.

Like `URLClassLoader`, `PreferredClassLoader` loads classes and resources from a search path of URLs. If a URL in the path ends with a `'/'`, it is assumed to refer to a directory; otherwise, the URL is assumed to refer to a JAR file.

The location of the first URL in the path can contain a preferred list for the entire path. A preferred list declares names of certain classes and other resources throughout the path as being preferred or not. When a `PreferredClassLoader` is asked to load a class or resource that is preferred (according to the preferred list) and the class or resource exists in the loader's path of URLs, the loader will not delegate first to its parent class loader as it otherwise would do; instead, it will attempt to load the class or resource from its own path of URLs only.

The preferred list for a path of URLs, if one exists, is located relative to the first URL in the path. If the first URL refers to a JAR file, then the preferred list is the contents of the file named `"META-INF/PREFERRED.LIST"` within that JAR file. If the first URL refers to a directory, then the preferred list is the contents of the file at the location `"META-INF/PREFERRED.LIST"` relative to that directory URL. If there is no preferred list at the required location, then no classes or resources are preferred for the path of URLs. A preferred list at any other location (such as relative to one of the other URLs in the path) is ignored.

Note that a class or resource is only considered to be preferred if the preferred list declares the name of the class or resource as being preferred and the class or resource actually exists in the path of URLs.

### Preferred List Syntax

A preferred list is a UTF-8 encoded text file, with lines separated by CR LF, LF, or CR (not followed by an LF). Multiple whitespace characters in a line are equivalent to a single whitespace character, and whitespace characters at the beginning or end of a line are ignored. If the first non-whitespace character of a line is `'#'`, the line is a comment and is equivalent to a blank line.

The first line of a preferred list must contain a version number in the following format:

         PreferredResources-Version: 1.x

This specification defines only version 1.0, but `PreferredClassLoader` will parse any version 1.x, x>=0 with the format and semantics specified here.

After the version number line, a preferred list comprises an optional default preferred entry followed by zero or more named preferred entries. A preferred list must contain either a default preferred entry or at least one named preferred entry. Blank lines are allowed before and after preferred entries, as well as between the lines of a named preferred entry.

A default preferred entry is a single line in the following format:

         Preferred: preferred-setting

where preferred-setting is a non-empty sequence of characters. If preferred-setting equals `"true"` (case insensitive), then resource names not matched by any of the named preferred entries are by default preferred; otherwise, resource names not matched by any of the named preferred entries are by default not preferred. If there is no default preferred entry, then resource names are by default not preferred.

A named preferred entry is two lines in the following format:

         Name: name-expression
         Preferred: preferred-setting

where name-expression and preferred-setting are non-empty sequences of characters. If preferred-setting equals `"true"` (case insensitive), then resource names that are matched by name-expression (and not any more specific named preferred entries) are preferred; otherwise, resource names that are matched by name-expression (and not any more specific named preferred entries) are not preferred.

If name-expression ends with `".class"`, it matches a class whose name is name-expression without the `".class"` suffix and with each `'/'` character replaced with a `'.'`, and it also matches any nested classes with an enclosing class of that name. Therefore, the preferred settings of a class and all of its nested classes are the same by default. It is possible, but strongly discouraged, to override the preferred setting of a nested class with a named preferred entry that explicitly matches the nested class's binary name. Named preferred entries for classes with binary names that start with `"java."` are ignored.

name-expression may match arbitrary resource names as well as class names, with path elements separated by `'/'` characters.

If name-expression ends with `"/"` or `"/*"`, then the entry is a directory wildcard entry that matches all resources (including classes) in the named directory. If name-expression ends with `"/-"`, then the entry is a namespace wildcard entry that matches all resources (including classes) in the named directory and all of its subdirectories.

When more than one named preferred entry matches a class or resource name, then the most specific entry takes precedence. A non-wildcard entry is more specific than a wildcard entry. A directory wildcard entry is more specific than a namespace wildcard entry. A namespace wildcard entry with more path elements is more specific than a namespace wildcard entry with fewer path elements. The order of named preferred entries is insignificant.

### Example Preferred List

Following is an example preferred list:

         PreferredResources-Version: 1.0
         Preferred: false

         Name: com/foo/FooBar.class
         Preferred: true

         Name: com/foo/*
         Preferred: false

         Name: com/foo/-
         Preferred: true

         Name: image-files/*
         Preferred: mumble

The class `com.foo.FooBar` is preferred, as well as any nested classes that have it as an enclosing class. All other classes in the `com.foo` package are not preferred because of the directory wildcard entry. Classes in subpackages of `com.foo` are preferred because of the namespace wildcard entry. Resources in the directory `"com/foo/"` are not preferred, and resources in subdirectories of `"com/foo/"` are preferred. Resources in the directory `"image-files/"` are not preferred because preferred settings other than `"true"` are interpreted as false. Classes that are in a package named `com.bar` are not preferred because of the default preferred entry.

Since:
  2.0
Implementation Specifics:

  This implementation uses the `Logger` named `net.jini.loader.pref.PreferredClassLoader.preferred` to log information at the following levels:

  Level | Description
  --- | ---
  `FINE` | names of preferred resources encountered

  This implementation uses the `Logger` named `net.jini.loader.pref.PreferredClassLoader.exception` to log information at the following levels:

  Level | Description
  --- | ---
  `HANDLED` | I/O exceptions caught trying to access a preferred list that are interpreted to indicate that the preferred list definitely does not exist

Constructor Summary
`PreferredClassLoader(URL[] urls, ClassLoader parent, String exportAnnotation, boolean requireDlPerm)` Creates a new `PreferredClassLoader` that loads classes and resources from the specified path of URLs and delegates to the specified parent class loader.

Method Summary
`protected Package` | `definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)`
`String` | `getClassAnnotation()` Returns the class annotation string for classes defined by this class loader. The returned value may be `null`. `PreferredClassLoader` implements this method as follows: If this `PreferredClassLoader` was constructed with a non-`null` export class annotation string, then this method returns that string.
`protected PermissionCollection` | `getPermissions(CodeSource codeSource)` Returns the static permissions to be automatically granted to classes loaded from the specified `CodeSource` and defined by this class loader.
`URL` | `getResource(String name)` Gets a resource with the specified name.
`protected boolean` | `isPreferredResource(String name, boolean isClass)` Returns `true` if a class or resource with the specified name is preferred for this class loader, and `false` if a class or resource with the specified name is not preferred for this loader.
`protected Class` | `loadClass(String name, boolean resolve)` Loads a class with the specified name.
`static PreferredClassLoader` | `newInstance(URL[] urls, ClassLoader parent, String exportAnnotation, boolean requireDlPerm)` Creates a new instance of `PreferredClassLoader` that loads classes and resources from the specified path of URLs and delegates to the specified parent class loader.
`String` | `toString()` Returns a string representation of this class loader.

Methods inherited from class java.net.URLClassLoader
`addURL, definePackage, findClass, findResource, findResources, getURLs, newInstance, newInstance`

Methods inherited from class java.security.SecureClassLoader
`defineClass`

Methods inherited from class java.lang.ClassLoader
`clearAssertionStatus, defineClass, defineClass, defineClass, findLibrary, findLoadedClass, findSystemClass, getPackage, getPackages, getParent, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners`

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

Constructor Detail

### PreferredClassLoader

    public PreferredClassLoader(URL[] urls,
                                ClassLoader parent,
                                String exportAnnotation,
                                boolean requireDlPerm)

  Creates a new `PreferredClassLoader` that loads classes and resources from the specified path of URLs and delegates to the specified parent class loader.

  If `exportAnnotation` is not `null`, then it will be used as the return value of the loader's `getClassAnnotation` method. If `exportAnnotation` is `null`, the loader's `getClassAnnotation` method will return a space-separated list of the URLs in the specified path. The `exportAnnotation` parameter can be used to specify so-called "export" URLs, from which other parties should load classes defined by the loader and which are different from the "import" URLs that the classes are actually loaded from.

  If `requireDlPerm` is `true`, the loader's `getPermissions` method will require that the `CodeSource` of any class defined by the loader is granted `DownloadPermission`.

Parameters:
  `urls` - the path of URLs to load classes and resources from
  `parent` - the parent class loader for delegation
  `exportAnnotation` - the export class annotation string to use for classes defined by this loader, or `null`
  `requireDlPerm` - if `true`, the loader will only define classes with a `CodeSource` that is granted `DownloadPermission`
Throws:
  `SecurityException` - if there is a security manager and an invocation of its `checkCreateClassLoader` method fails

Method Detail

### newInstance

    public static PreferredClassLoader newInstance(URL[] urls,
                                                   ClassLoader parent,
                                                   String exportAnnotation,
                                                   boolean requireDlPerm)

  Creates a new instance of `PreferredClassLoader` that loads classes and resources from the specified path of URLs and delegates to the specified parent class loader.

  The `exportAnnotation` and `requireDlPerm` parameters have the same semantics as they do for the constructor.

  The `loadClass` method of the returned `PreferredClassLoader` will, if there is a security manager, invoke its `checkPackageAccess` method with the package name of the class to load before attempting to load the class; this could result in a `SecurityException` being thrown from `loadClass`.

  Parameters:
    `urls` - the path of URLs to load classes and resources from
    `parent` - the parent class loader for delegation
    `exportAnnotation` - the export class annotation string to use for classes defined by this loader, or `null`
    `requireDlPerm` - if `true`, the loader will only define classes with a `CodeSource` that is granted `DownloadPermission`
  Returns:
    the new `PreferredClassLoader` instance
  Throws:
    `SecurityException` - if the current security context does not have the permissions necessary to connect to all of the URLs in `urls`

### isPreferredResource

    protected boolean isPreferredResource(String name,
                                          boolean isClass)
                                   throws IOException

  Returns `true` if a class or resource with the specified name is preferred for this class loader, and `false` if a class or resource with the specified name is not preferred for this loader.

  If `isClass` is `true`, then `name` is interpreted as the binary name of a class; otherwise, `name` is interpreted as the full path of a resource.

  This method only returns `true` if a class or resource with the specified name exists in the this loader's path of URLs and the name is preferred in the preferred list. This method returns `false` if the name is not preferred in the preferred list or if the name is preferred with the default preferred entry or a wildcard preferred entry and the class or resource does not exist in the path of URLs.

  Parameters:
    `name` - the name of the class or resource
    `isClass` - `true` if `name` is a binary class name, and `false` if `name` is the full path of a resource
  Returns:
    `true` if a class or resource named `name` is preferred for this loader, and `false` if a class or resource named `name` is not preferred for this loader
  Throws:
    `IOException` - if the preferred list cannot definitely be determined to exist or not exist, or if the preferred list contains a syntax error, or if the name is preferred with the default preferred entry or a wildcard preferred entry and the class or resource cannot definitely be determined to exist or not exist in the path of URLs, or if the name is preferred with a non-wildcard entry and the class or resource does not exist or cannot definitely be determined to exist in the path of URLs

### loadClass

    protected Class loadClass(String name,
                              boolean resolve)
                       throws ClassNotFoundException

  Loads a class with the specified name.

  `PreferredClassLoader` implements this method as follows:

  This method first invokes `findLoadedClass` with `name`; if `findLoadedClass` returns a non-`null` `Class`, then this method returns that `Class`.

  Otherwise, this method invokes `isPreferredResource` with `name` as the first argument and `true` as the second argument:

  - If `isPreferredResource` throws an `IOException`, then this method throws a `ClassNotFoundException` containing the `IOException` as its cause.
  - If `isPreferredResource` returns `true`, then this method invokes `findClass` with `name`. If `findClass` throws an exception, then this method throws that exception. Otherwise, this method returns the `Class` returned by `findClass`, and if `resolve` is `true`, `resolveClass` is invoked with the `Class` before returning.
  - If `isPreferredResource` returns `false`, then this method invokes the superclass implementation of `loadClass` with `name` and `resolve` and returns the result. If the superclass's `loadClass` throws an exception, then this method throws that exception.

  Parameters:
    `name` - the binary name of the class to load
    `resolve` - if `true`, then `resolveClass` will be invoked with the loaded class before returning
  Returns:
    the loaded class
  Throws:
    `ClassNotFoundException` - if the class could not be found

### getResource

    public URL getResource(String name)

  Gets a resource with the specified name.

  `PreferredClassLoader` implements this method as follows:

  This method invokes `isPreferredResource` with `name` as the first argument and `false` as the second argument:

  - If `isPreferredResource` throws an `IOException`, then this method returns `null`.
  - If `isPreferredResource` returns `true`, then this method invokes `findResource` with `name` and returns the result.
  - If `isPreferredResource` returns `false`, then this method invokes the superclass implementation of `getResource` with `name` and returns the result.

  Parameters:
    `name` - the name of the resource to get
  Returns:
    a `URL` for the resource, or `null` if the resource could not be found

### definePackage

    protected Package definePackage(String name,
                                    String specTitle,
                                    String specVersion,
                                    String specVendor,
                                    String implTitle,
                                    String implVersion,
                                    String implVendor,
                                    URL sealBase)

### getClassAnnotation

    public String getClassAnnotation()

  Returns the class annotation string for classes defined by this class loader. The returned value may be `null`.

  `PreferredClassLoader` implements this method as follows:

  If this `PreferredClassLoader` was constructed with a non-`null` export class annotation string, then this method returns that string. Otherwise, this method returns a space-separated list of this loader's path of URLs.

  Specified by:
    `getClassAnnotation` in interface `ClassAnnotation`
  Returns:
    the class annotation string for classes defined by this loader, or `null`

### getPermissions

    protected PermissionCollection getPermissions(CodeSource codeSource)

  Returns the static permissions to be automatically granted to classes loaded from the specified `CodeSource` and defined by this class loader.

  `PreferredClassLoader` implements this method as follows:

  If there is a security manager and this `PreferredClassLoader` was constructed to enforce `DownloadPermission`, then this method checks that the current security policy grants the specified `CodeSource` the permission `DownloadPermission("permit")`; if that check fails, then this method throws a `SecurityException`.

  Then this method invokes the superclass implementation of `getPermissions` and returns the result.

  Parameters:
    `codeSource` - the `CodeSource` to return the permissions to be granted to
  Returns:
    the permissions to be granted to the `CodeSource`
  Throws:
    `SecurityException` - if there is a security manager, this `PreferredClassLoader` was constructed to enforce `DownloadPermission`, and the current security policy does not grant the specified `CodeSource` the permission `DownloadPermission("permit")`

### toString

    public String toString()

  Returns a string representation of this class loader.

Overview | Package | Class | Use | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

Copyright © 2004 Sun Microsystems, Inc. All rights reserved