public class PreferredClassProvider extends RMIClassLoaderSpi
RMIClassLoader provider that supports preferred classes.
See the RMIClassLoader specification for information about how to install and
configure the RMIClassLoader service provider.
PreferredClassProvider uses instances of PreferredClassLoader to load
classes from codebase URL paths supplied to RMIClassLoader.loadClass methods.
PreferredClassProvider does not enforce DownloadPermission by default,
but a subclass can configure it to do so by passing true as the argument to the
protected constructor.
By overriding the getClassAnnotation(ClassLoader)
method, a subclass can also configure the class annotations to be used for classes defined by the
system class loader, its ancestor class loaders, and any class loader that is not an instance of
ClassAnnotation or URLClassLoader.
PreferredClassProvider implements the abstract methods of
RMIClassLoaderSpi. Where applicable, these definitions and descriptions are
relative to the instance of PreferredClassProvider on which a method is invoked and
the context in which it is invoked.
The annotation string for a class loader is determined by the following procedure:
getClassAnnotation(ClassLoader) with the loader.
ClassAnnotation, the annotation string is
the result of invoking getClassAnnotation on the
loader.
URLClassLoader, the annotation string is a
space-separated list of the URLs returned by an invocation of getURLs on the loader.
getClassAnnotation(ClassLoader) with the loader.
URL(String) constructor; if such parsing would result in a
MalformedURLException, then the annotation URL path for the loader is only defined to the
extent that it is not equal to any other path of URLs.
A PreferredClassProvider maintains an internal table of class loader instances
indexed by keys that comprise a path of URLs and a parent class loader. The table does not
strongly reference the class loader instances, in order to allow them (and the classes they have
defined) to be garbage collected when they are not otherwise reachable.
The methods loadClass, loadProxyClass, and getClassLoader, which each have a String parameter named
codebase, have the following behaviors in common:
codebase may be null. If it is not null, it is
interpreted as a path of URLs by parsing it as a list of URLs separated by spaces, where each URL
is parsed as with the URL(String) constructor; this could result in a MalformedURLException. This path of URLs is the codebase URL path for the invocation.
codebase
and the current thread's context class loader as follows. If codebase is
null, then the codebase loader is the current thread's context class loader.
Otherwise, for each non-null loader starting with the current thread's context class
loader and continuing with each successive parent class loader, if the codebase URL path is equal
to the loader's annotation URL path, then the codebase loader is that loader. If no such
matching loader is found, then the codebase loader is the loader in this
PreferredClassProvider's internal table with the codebase URL path as the key's path
of URLs and the current thread's context class loader as the key's parent class loader. If no
such entry exists in the table, then one is created by invoking createClassLoader with the codebase URL path, the current thread's context class loader, and the
boolean requireDlPerm value that this PreferredClassProvider
was constructed with; the created loader is added to the table, and it is chosen as the codebase
loader.
openConnection().getPermission()
on the URL object is not a FilePermission or if it is a
FilePermission whose name does not contain a directory separator, then that
permission is the appropriate permission. If it is a FilePermission whose name
contains a directory separator, then the appropriate permission is a FilePermission
with action "read" and the same name except with the last path segment replaced with
"-" (that is, permission to read all files in the same directory and all
subdirectories).
When PreferredClassProvider attempts to load a class (or interface) named
N using class loader L, it does so in a manner equivalent
to evaluating the following expression:
Class.forName(N, false, L)
In particular, the case of N being the binary name of an array class is
supported.This implementation uses the Logger named net.jini.loader.pref.PreferredClassProvider
to log information at the following levels:
| Level | Description |
|---|---|
FINE | class loading failures |
HANDLED | exceptions caught during class loading operations |
FINE | invocations of loadClass and loadProxyClass
|
FINEST | detailed activity of loadClass and
loadProxyClass implementations
|
| Modifier | Constructor and Description |
|---|---|
|
PreferredClassProvider()
Creates a new
PreferredClassProvider. |
protected |
PreferredClassProvider(boolean requireDlPerm)
Creates a new
PreferredClassProvider. |
| Modifier and Type | Method and Description |
|---|---|
protected ClassLoader |
createClassLoader(URL[] urls,
ClassLoader parent,
boolean requireDlPerm)
Creates the class loader for this
PreferredClassProvider to use to load classes
from the specified path of URLs with the specified delegation parent. |
String |
getClassAnnotation(Class cl)
Provides the implementation for
RMIClassLoaderSpi.getClassAnnotation(Class). |
protected String |
getClassAnnotation(ClassLoader loader)
Returns the annotation string for the specified class loader.
|
ClassLoader |
getClassLoader(String codebase)
Provides the implementation for
RMIClassLoaderSpi.getClassLoader(String). |
Class |
loadClass(String codebase,
String name,
ClassLoader defaultLoader)
Provides the implementation for
RMIClassLoaderSpi.loadClass(String, String,
ClassLoader). |
Class |
loadProxyClass(String codebase,
String[] interfaceNames,
ClassLoader defaultLoader)
Provides the implementation of
RMIClassLoaderSpi.loadProxyClass(String, String[],
ClassLoader). |
public PreferredClassProvider()
PreferredClassProvider.
This constructor is used by the RMIClassLoader service provider location mechanism
when PreferredClassProvider is configured as the RMIClassLoader
provider class.
If there is a security manager, its checkCreateClassLoader method is invoked; this could result in a
SecurityException.
DownloadPermission is not enforced by the created provider.
SecurityException - if there is a security manager and the invocation of its
checkCreateClassLoader method failsprotected PreferredClassProvider(boolean requireDlPerm)
PreferredClassProvider.
This constructor is used by subclasses to control whether or not DownloadPermission is enforced.
If there is a security manager, its checkCreateClassLoader method is invoked; this could result in a
SecurityException.
requireDlPerm - if true, the class loaders created by the provider will
only define classes with a CodeSource that is granted DownloadPermissionSecurityException - if there is a security manager and the invocation of its
checkCreateClassLoader method failspublic Class loadClass(String codebase, String name, ClassLoader defaultLoader) throws MalformedURLException, ClassNotFoundException
RMIClassLoaderSpi.loadClass(String, String,
ClassLoader).
PreferredClassProvider implements this method as follows:
If name is the binary name of an array class (of one or more dimensions) with
a primitive element type, this method returns the Class for that array class.
Otherwise, if defaultLoader is not null and any of the following
conditions are true:
codebase is null.
defaultLoader.
PreferredClassLoader.
PreferredClassLoader and an invocation
of isPreferredResource on the codebase
loader with the class name described below as the first argument and true as the
second argument returns false. If name is the binary name of an
array class (of one or more dimensions) with a element type that is a reference type, the
class name passed to isPreferredResource is the binary name of that element
type; otherwise, the class name passed to isPreferredResource is
name. This invocation is only done if none of the previous conditions are true.
If isPreferredResource throws an IOException, this method throws a
ClassNotFoundException.
defaultLoader. If this attempt succeeds, this method returns the resulting
Class; if it throws a ClassNotFoundException, this method proceeds
as follows.
Otherwise, this method attempts to load the class with the specified name using the
codebase loader, if there is a security manager and the current security context has
permission to access the codebase loader, or using the current thread's context class loader
otherwise. If this attempt succeeds, this method returns the resulting Class;
if it throws a ClassNotFoundException, this method throws a
ClassNotFoundException.
loadClass in class RMIClassLoaderSpicodebase - the codebase URL path as a space-separated list of URLs, or
nullname - the binary name of the class to loaddefaultLoader - additional contextual class loader to use, or nullClass object representing the loaded classMalformedURLException - if codebase is non-null and contains
an invalid URLClassNotFoundException - if a definition for the class could not be loadedpublic String getClassAnnotation(Class cl)
RMIClassLoaderSpi.getClassAnnotation(Class).
PreferredClassProvider implements this method as follows:
If cl is an array class (of one or more dimensions) with a primitive element
type, this method returns null.
Otherwise, this method returns the annotation string for the defining class loader of
cl, except that if the annotation string would be determined by an invocation of
URLClassLoader.getURLs on that loader and the current security
context does not have the permissions necessary to connect to each URL returned by that
invocation (where the permission to connect to a URL is determined by invoking openConnection().getPermission() on
the URL object), this method returns the result of invoking getClassAnnotation(ClassLoader) with the loader instead.
getClassAnnotation in class RMIClassLoaderSpicl - the class to obtain the annotation string fornullprotected String getClassAnnotation(ClassLoader loader)
This method is invoked in order to determine the annotation string for the system class
loader, an ancestor of the system class loader, any class loader that is not an instance of
ClassAnnotation or URLClassLoader, or (for an invocation of getClassAnnotation(Class)) a URLClassLoader for
which the current security context does not have the permissions necessary to connect to all
of its URLs.
PreferredClassProvider implements this method as follows:
This method returns the value of the system property "java.rmi.server.codebase"
(or possibly an earlier cached value).
loader - the class loader to obtain the annotation string fornullpublic ClassLoader getClassLoader(String codebase) throws MalformedURLException
RMIClassLoaderSpi.getClassLoader(String).
PreferredClassProvider implements this method as follows:
If there is a security manager, its checkPermission method is invoked with a
RuntimePermission("getClassLoader") permission; this could result in a
SecurityException. Also, if there is a security manager, the codebase loader is
not the current thread's context class loader, and the current security context does not have
permission to access the codebase loader, this method throws a SecurityException.
This method returns the codebase loader if there is a security manager, or the current thread's context class loader otherwise.
getClassLoader in class RMIClassLoaderSpicodebase - the codebase URL path as a space-separated list of URLs, or
nullMalformedURLException - if codebase is non-null and contains
an invalid URLSecurityException - if there is a security manager and the invocation of its
checkPermission method fails, or if the current
security context does not have the permissions necessary to
connect to all of the URLs in the codebase URL pathpublic Class loadProxyClass(String codebase, String[] interfaceNames, ClassLoader defaultLoader) throws MalformedURLException, ClassNotFoundException
RMIClassLoaderSpi.loadProxyClass(String, String[],
ClassLoader).
PreferredClassProvider implements this method as follows:
If defaultLoader is not null and any of the following conditions
are true:
codebase is null.
defaultLoader.
PreferredClassLoader.
PreferredClassLoader and an invocation
of isPreferredResource on the codebase
loader for each element of interfaces, with the element as the first argument
and true as the second argument, all return false. These
invocations are only done if none of the previous conditions are true. If any invocation of
isPreferredResource throws an IOException, this method throws a
ClassNotFoundException.
interfaces using defaultLoader. If all of the interfaces are
loaded successfully, then
public: if there is a security manager,
the codebase loader is the current thread's context class loader or the current security
context has permission to access the codebase loader, and the annotation URL path for the
codebase loader is not equal to the annotation URL path for defaultLoader, this
method first attempts to get a dynamic proxy class (using Proxy.getProxyClass) that is defined by the codebase loader and that implements all of the
interfaces, and if this attempt succeeds, this method returns the resulting
Class. Otherwise, this method attempts to get a dynamic proxy class that is
defined by defaultLoader and that implements all of the interfaces. If that
attempt succeeds, this method returns the resulting Class; if it throws an
IllegalArgumentException, this method throws a ClassNotFoundException.
public interfaces are defined by the same class loader:
this method attempts to get a dynamic proxy class that is defined by that loader and that
implements all of the interfaces. If this attempt succeeds, this method returns the
resulting Class; if it throws an IllegalArgumentException, this
method throws a ClassNotFoundException.
public interfaces defined by
different class loaders): this method throws a LinkageError.
ClassNotFoundException,
this method proceeds as follows.
Otherwise, this method attempts to load all of the interfaces named by the elements of
interfaces using the codebase loader, if there is a security manager and the
current security context has permission to access the codebase loader, or using the current
thread's context class loader otherwise. If all of the interfaces are loaded successfully,
then
public: this method attempts to get a
dynamic proxy class that is defined by the loader used to load the interfaces and that
implements all of the interfaces. If this attempt succeeds, this method returns the
resulting Class; if it throws an IllegalArgumentException, this
method throws a ClassNotFoundException.
public interfaces are defined by the same class loader:
this method attempts to get a dynamic proxy class that is defined by that loader and that
implements all of the interfaces. If this attempt succeeds, this method returns the
resulting Class; if it throws an IllegalArgumentException, this
method throws a ClassNotFoundException.
public interfaces defined by
different class loaders): this method throws a LinkageError.
ClassNotFoundException,
this method throws a ClassNotFoundException.loadProxyClass in class RMIClassLoaderSpicodebase - the codebase URL path as a space-separated list of URLs, or
nullinterfaceNames - the binary names of the interfaces for the proxy class to implementdefaultLoader - additional contextual class loader to use, or nullMalformedURLException - if codebase is non-null and contains
an invalid URLClassNotFoundException - if a definition for one of the named interfaces could not be
loaded, or if creation of the dynamic proxy class failed (such
as if Proxy.getProxyClass would throw an
IllegalArgumentException for the given interface
list)protected ClassLoader createClassLoader(URL[] urls, ClassLoader parent, boolean requireDlPerm)
PreferredClassProvider to use to load classes
from the specified path of URLs with the specified delegation parent.
PreferredClassProvider implements this method as follows:
This method creates a new instance of PreferredClassLoader that loads classes and
resources from urls, delegates to parent, and enforces DownloadPermission if requireDlPerm is true. The created loader
uses a restricted security context to ensure that the URL retrieval operations undertaken by
the loader cannot exercise a permission that is not implied by the permissions necessary to
access the loader as a codebase loader for the specified path of URLs.
urls - the path of URLs to load classes and resources fromparent - the parent class loader for delegationrequireDlPerm - if true, the loader must only define classes with a CodeSource that is granted DownloadPermissionCopyright © GigaSpaces.