Class RMIClassLoader
RMIClassLoader
comprises static methods to support
dynamic class loading with RMI. Included are methods for loading
classes from a network location (one or more URLs) and obtaining
the location from which an existing class should be loaded by
remote parties. These methods are used by the RMI runtime when
marshalling and unmarshalling classes contained in the arguments
and return values of remote method calls.
The implementation of the following static methods
loadClass(URL,String)
loadClass(String,String)
loadClass(String,String,ClassLoader)
loadProxyClass(String,String[],ClassLoader)
getClassLoader(String)
getClassAnnotation(Class)
RMIClassLoaderSpi
, the
service provider interface for those methods. When one of the
methods is invoked, its behavior is to delegate to a corresponding
method on the service provider instance. The details of how each
method delegates to the provider instance is described in the
documentation for each particular method.
The service provider instance is chosen as follows:
- If the system property
java.rmi.server.RMIClassLoaderSpi
is defined, then if its value equals the string"default"
, the provider instance will be the value returned by an invocation of thegetDefaultProviderInstance()
method, and for any other value, if a class named with the value of the property can be loaded by the system class loader (seeClassLoader.getSystemClassLoader()
) and that class is assignable toRMIClassLoaderSpi
and has a public no-argument constructor, then that constructor will be invoked to create the provider instance. If the property is defined but any other of those conditions are not true, then an unspecifiedError
will be thrown to code that attempts to useRMIClassLoader
, indicating the failure to obtain a provider instance. - If a resource named
META-INF/services/java.rmi.server.RMIClassLoaderSpi
is visible to the system class loader, then the contents of that resource are interpreted as a provider-configuration file, and the first class name specified in that file is used as the provider class name. If a class with that name can be loaded by the system class loader and that class is assignable toRMIClassLoaderSpi
and has a public no-argument constructor, then that constructor will be invoked to create the provider instance. If the resource is found but a provider cannot be instantiated as described, then an unspecifiedError
will be thrown to code that attempts to useRMIClassLoader
, indicating the failure to obtain a provider instance. - Otherwise, the provider instance will be the value returned by
an invocation of the
getDefaultProviderInstance()
method.
- Since:
- 1.1
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionstatic String
getClassAnnotation
(Class<?> cl) Returns the annotation string (representing a location for the class definition) that RMI will use to annotate the class descriptor when marshalling objects of the given class.static ClassLoader
getClassLoader
(String codebase) Returns a class loader that loads classes from the given codebase URL path.static RMIClassLoaderSpi
Returns the canonical instance of the default provider for the service provider interfaceRMIClassLoaderSpi
.static Object
getSecurityContext
(ClassLoader loader) Deprecated.no replacement.static Class
<?> Deprecated.replaced byloadClass(String,String)
methodstatic Class
<?> Loads a class from a codebase URL path.static Class
<?> loadClass
(String codebase, String name, ClassLoader defaultLoader) Loads a class from a codebase URL path, optionally using the supplied loader.static Class
<?> Loads a class from a codebase URL.static Class
<?> loadProxyClass
(String codebase, String[] interfaces, ClassLoader defaultLoader) Loads a dynamic proxy class (seeProxy
) that implements a set of interfaces with the given names from a codebase URL path.
-
Method Details
-
loadClass
@Deprecated public static Class<?> loadClass(String name) throws MalformedURLException, ClassNotFoundException Deprecated.replaced byloadClass(String,String)
methodLoads the class with the specifiedname
.This method delegates to
loadClass(String,String)
, passingnull
as the first argument andname
as the second argument.- Parameters:
name
- the name of the class to load- Returns:
- the
Class
object representing the loaded class - Throws:
MalformedURLException
- if a provider-specific URL used to load classes is invalidClassNotFoundException
- if a definition for the class could not be found at the codebase location- See Also:
-
loadClass
public static Class<?> loadClass(URL codebase, String name) throws MalformedURLException, ClassNotFoundException Loads a class from a codebase URL. Ifcodebase
isnull
, then this method will behave the same asloadClass(String,String)
with anull
codebase
and the given class name.This method delegates to the
RMIClassLoaderSpi.loadClass(String,String,ClassLoader)
method of the provider instance, passing the result of invokingURL.toString()
on the given URL (ornull
ifcodebase
is null) as the first argument,name
as the second argument, andnull
as the third argument.- Parameters:
codebase
- the URL to load the class from, ornull
name
- the name of the class to load- Returns:
- the
Class
object representing the loaded class - Throws:
MalformedURLException
- ifcodebase
isnull
and a provider-specific URL used to load classes is invalidClassNotFoundException
- if a definition for the class could not be found at the specified URL
-
loadClass
public static Class<?> loadClass(String codebase, String name) throws MalformedURLException, ClassNotFoundException Loads a class from a codebase URL path.This method delegates to the
RMIClassLoaderSpi.loadClass(String,String,ClassLoader)
method of the provider instance, passingcodebase
as the first argument,name
as the second argument, andnull
as the third argument.- Parameters:
codebase
- the list of URLs (separated by spaces) to load the class from, ornull
name
- the name of the class to load- Returns:
- the
Class
object representing the loaded class - Throws:
MalformedURLException
- ifcodebase
is non-null
and contains an invalid URL, or ifcodebase
isnull
and a provider-specific URL used to load classes is invalidClassNotFoundException
- if a definition for the class could not be found at the specified location- Since:
- 1.2
-
loadClass
public static Class<?> loadClass(String codebase, String name, ClassLoader defaultLoader) throws MalformedURLException, ClassNotFoundException Loads a class from a codebase URL path, optionally using the supplied loader. This method should be used when the caller would like to make available to the provider implementation an additional contextual class loader to consider, such as the loader of a caller on the stack. Typically, a provider implementation will attempt to resolve the named class using the givendefaultLoader
, if specified, before attempting to resolve the class from the codebase URL path.This method delegates to the
RMIClassLoaderSpi.loadClass(String,String,ClassLoader)
method of the provider instance, passingcodebase
as the first argument,name
as the second argument, anddefaultLoader
as the third argument.- Parameters:
codebase
- the list of URLs (separated by spaces) to load the class from, ornull
name
- the name of the class to loaddefaultLoader
- additional contextual class loader to use, ornull
- Returns:
- the
Class
object representing the loaded class - Throws:
MalformedURLException
- ifcodebase
is non-null
and contains an invalid URL, or ifcodebase
isnull
and a provider-specific URL used to load classes is invalidClassNotFoundException
- if a definition for the class could not be found at the specified location- Since:
- 1.4
-
loadProxyClass
public static Class<?> loadProxyClass(String codebase, String[] interfaces, ClassLoader defaultLoader) throws ClassNotFoundException, MalformedURLException Loads a dynamic proxy class (seeProxy
) that implements a set of interfaces with the given names from a codebase URL path.The interfaces will be resolved similar to classes loaded via the
loadClass(String,String)
method using the givencodebase
.This method delegates to the
RMIClassLoaderSpi.loadProxyClass(String,String[],ClassLoader)
method of the provider instance, passingcodebase
as the first argument,interfaces
as the second argument, anddefaultLoader
as the third argument.- Parameters:
codebase
- the list of URLs (space-separated) to load classes from, ornull
interfaces
- the names of the interfaces for the proxy class to implementdefaultLoader
- additional contextual class loader to use, ornull
- Returns:
- a dynamic proxy class that implements the named interfaces
- Throws:
MalformedURLException
- ifcodebase
is non-null
and contains an invalid URL, or ifcodebase
isnull
and a provider-specific URL used to load classes is invalidClassNotFoundException
- if a definition for one of the named interfaces could not be found at the specified location, or if creation of the dynamic proxy class failed (such as ifProxy.getProxyClass(ClassLoader,Class[])
would throw anIllegalArgumentException
for the given interface list)- Since:
- 1.4
-
getClassLoader
Returns a class loader that loads classes from the given codebase URL path.The class loader returned is the class loader that the
loadClass(String,String)
method would use to load classes for the samecodebase
argument.This method delegates to the
RMIClassLoaderSpi.getClassLoader(String)
method of the provider instance, passingcodebase
as the argument.- Parameters:
codebase
- the list of URLs (space-separated) from which the returned class loader will load classes from, ornull
- Returns:
- a class loader that loads classes from the given codebase URL path
- Throws:
MalformedURLException
- ifcodebase
is non-null
and contains an invalid URL, or ifcodebase
isnull
and a provider-specific URL used to identify the class loader is invalid- Since:
- 1.3
-
getClassAnnotation
Returns the annotation string (representing a location for the class definition) that RMI will use to annotate the class descriptor when marshalling objects of the given class.This method delegates to the
RMIClassLoaderSpi.getClassAnnotation(Class)
method of the provider instance, passingcl
as the argument.- Parameters:
cl
- the class to obtain the annotation for- Returns:
- a string to be used to annotate the given class when
it gets marshalled, or
null
- Throws:
NullPointerException
- ifcl
isnull
- Since:
- 1.2
-
getDefaultProviderInstance
Returns the canonical instance of the default provider for the service provider interfaceRMIClassLoaderSpi
. If the system propertyjava.rmi.server.RMIClassLoaderSpi
is not defined, then theRMIClassLoader
static methodsloadClass(URL,String)
loadClass(String,String)
loadClass(String,String,ClassLoader)
loadProxyClass(String,String[],ClassLoader)
getClassLoader(String)
getClassAnnotation(Class)
The default service provider instance implements
RMIClassLoaderSpi
as follows:The
getClassAnnotation
method returns aString
representing the codebase URL path that a remote party should use to download the definition for the specified class. The format of the returned string is a path of URLs separated by spaces. The codebase string returned depends on the defining class loader of the specified class:If the class loader is the system class loader (see
ClassLoader.getSystemClassLoader()
), a parent of the system class loader such as the loader used for installed extensions, or the bootstrap class loader (which may be represented bynull
), then the value of thejava.rmi.server.codebase
property (or possibly an earlier cached value) is returned, ornull
is returned if that property is not set.Otherwise, if the class loader is an instance of
URLClassLoader
, then the returned string is a space-separated list of the external forms of the URLs returned by invoking thegetURLs
methods of the loader.Finally, if the class loader is not an instance of
URLClassLoader
, then the value of thejava.rmi.server.codebase
property (or possibly an earlier cached value) is returned, ornull
is returned if that property is not set.
For the implementations of the methods described below, which all take a
String
parameter namedcodebase
that is a space-separated list of URLs, thecodebase
argument is ignored. Class loading proceeds using the the current thread's context class loader (seeThread.getContextClassLoader()
), which is also considered to be the codebase loader, irrespective of any value passed as thecodebase
argument.The
getClassLoader
method returns the current thread's context class loader.The
loadClass
method attempts to load the class with the specified name as follows:If the
defaultLoader
argument is non-null
, it first attempts to load the class with the specifiedname
using thedefaultLoader
, as if by evaluatingClass.forName(name, false, defaultLoader)
If the class is successfully loaded from thedefaultLoader
, that class is returned. If an exception other thanClassNotFoundException
is thrown, that exception is thrown to the caller.Next, the
loadClass
method attempts to load the class with the specifiedname
using the current thread's context class loader.The
loadProxyClass
method attempts to return a dynamic proxy class with the named interface as follows:If the
defaultLoader
argument is non-null
and all of the named interfaces can be resolved through that loader, then,- if all of the resolved interfaces are
public
, then it first attempts to obtain a dynamic proxy class (usingProxy.getProxyClass
) for the resolved interfaces defined in the codebase loader; if that attempt throws anIllegalArgumentException
, it then attempts to obtain a dynamic proxy class for the resolved interfaces defined in thedefaultLoader
. If both attempts throwIllegalArgumentException
, then this method throws aClassNotFoundException
. If any other exception is thrown, that exception is thrown to the caller. - if all of the non-
public
resolved interfaces are defined in the same class loader, then it attempts to obtain a dynamic proxy class for the resolved interfaces defined in that loader. - otherwise, a
LinkageError
is thrown (because a class that implements all of the specified interfaces cannot be defined in any loader).
Otherwise, if all of the named interfaces can be resolved through the codebase loader, then,
- if all of the resolved interfaces are
public
, then it attempts to obtain a dynamic proxy class for the resolved interfaces in the codebase loader. If the attempt throws anIllegalArgumentException
, then this method throws aClassNotFoundException
. - if all of the non-
public
resolved interfaces are defined in the same class loader, then it attempts to obtain a dynamic proxy class for the resolved interfaces defined in that loader. - otherwise, a
LinkageError
is thrown (because a class that implements all of the specified interfaces cannot be defined in any loader).
Otherwise, a
ClassNotFoundException
is thrown for one of the named interfaces that could not be resolved.- Returns:
- the canonical instance of the default service provider
- Since:
- 1.4
-
getSecurityContext
Deprecated.no replacement. This method has no purpose in the absence of a Security Manager.Always returns null.- Parameters:
loader
- a class loader from which to get the security context- Returns:
- null
-