public final class ClassLoading extends Object
RMIClassLoaderSpi with optional verification that the codebase URIs
used to load classes provide content integrity (see Security.verifyCodebaseIntegrity).
Traditionally a class extending RMIClassLoaderSpi is determined by setting
the system property "java.rmi.server.RMIClassLoaderSpi", or alternatively,
RMIClassLoaderSpi may also be defined by RMIClassLoader
using a provider visible to the ClassLoader returned by
ClassLoader.getSystemClassLoader() with ServiceLoader.
As explained in River-336 this isn't always practical for IDE's or other
frameworks. To solve River-336, ClassLoading now uses ServiceLoader
to determine a RMIClassLoaderSpi provider, however unlike
RMIClassLoader, by default it uses ClassLoading's ClassLoader.getResources(java.lang.String)
instance to find providers.
To define a new RMIClassLoaderSpi for River to utilize, create a file in your providers jar file called:
META-INF/services/java.rmi.server.RMIClassLoaderSpi
This file should contain a single line with the fully qualified name of your RMIClassLoaderSpi implementation.
ClassLoading will iterate through all RMIClassLoaderSpi implementations found until it finds one defined by the system property:
System.getProperty("net.jini.loader.ClassLoading.provider");
If this System property is not defined, ClassLoading will load
net.jini.loader.pref.PreferredClassProvider, alternatively
java.rmi.server.RMIClassLoader delegates all calls to RMIClassLoader.
If a provider is not found, it will not be updated.
Gregg Wonderly originally reported River-336 and provided a patch
containing a new CodebaseAccessClassLoader to replace RMIClassLoader,
later Sim Isjkes created RiverClassLoader that utilized ServiceLoader.
Both implementations contained methods identical to RMIClassLoaderSpi,
however new implementations were required to extend new provider
implementations, creating a compatibility issue with existing implementations
extending RMIClassLoaderSpi. For backward compatibility with existing
implementations, RMIClassLoaderSpi has been retained as the provider,
avoiding the need to recompile client code. The abilities of both
implementations, to use ServiceLoader, or to define a provider using a method
call have been retained, with the restriction that implementations are to be
obtained via ServiceLoader.
Instead, all that is required for utilization of existing service provider
RMIClassLoaderSpi implementations is to set the system property
"net.jini.loader.ClassLoading.provider".
| Modifier and Type | Method and Description |
|---|---|
static String |
getClassAnnotation(Class<?> cl)
Returns the annotation string (representing a location for
the class definition as a single or space delimited list of
RFC3986 compliant URI) that JERI 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
RFC3986 compliant URI path.
|
static RMIClassLoaderSpi |
getProvider()
The current RMIClassLoaderSpi provider in use by ClassLoading.
|
static boolean |
installNewProvider(String providerName,
ClassLoader providerLoader)
Installs a new RMIClassLoaderSpi provider with the ClassLoader
provided.
|
static Class<?> |
loadClass(String codebase,
String name,
ClassLoader defaultLoader,
boolean verifyCodebaseIntegrity,
ClassLoader verifierLoader)
Loads a class using
RMIClassLoaderSpi.loadClass(String,String,ClassLoader),
optionally verifying that the RFC3986 compliant
codebase URIs provide content integrity. |
static Class<?> |
loadProxyClass(String codebase,
String[] interfaceNames,
ClassLoader defaultLoader,
boolean verifyCodebaseIntegrity,
ClassLoader verifierLoader)
Loads a dynamic proxy class using
RMIClassLoaderSpi.loadProxyClass(String,String[],ClassLoader),
optionally verifying that the RFC3986 compliant
codebase URIs provide content integrity. |
public static RMIClassLoaderSpi getProvider()
SecurityException - if caller doesn't have RuntimePermission "getFactory"public static boolean installNewProvider(String providerName, ClassLoader providerLoader)
providerName - fully defined class name of the provider, if null,
a new provider instance will be determined by system properties.providerLoader - The class loader to be used to load
provider-configuration files and provider classes, or null if the
system class loader (or, failing that, the bootstrap class loader)
is to be used.SecurityException - if caller doesn't have RuntimePermission "getFactory"public static ClassLoader getClassLoader(String codebase) throws MalformedURLException, SecurityException
This method delegates to the
RMIClassLoaderSpi.getClassLoader(String) method
of the provider instance, passing codebase as the argument.
If there is a security manger, its checkPermission
method will be invoked with a
RuntimePermission("getClassLoader") permission;
this could result in a SecurityException.
The provider implementation of this method may also perform further
security checks to verify that the calling context has permission to
connect to all of the URIs in the codebase URI path.
codebase - the list of URIs (space-separated) from which
the returned class loader will load classes from, or nullMalformedURLException - if codebase is
non-null and contains an non RFC3986 compliant URI, or
if codebase is null and a provider-specific
URL used to identify the class loader is invalidSecurityException - if there is a security manager and the
invocation of its checkPermission method fails, or
if the caller does not have permission to connect to all of the
URIs in the codebase URI pathpublic static String getClassAnnotation(Class<?> cl)
This method delegates to the
RMIClassLoaderSpi.getClassAnnotation(Class) method
of the provider instance, passing cl as the argument.
cl - the class to obtain the annotation fornullNullPointerException - if cl is nullpublic static Class<?> loadClass(String codebase, String name, ClassLoader defaultLoader, boolean verifyCodebaseIntegrity, ClassLoader verifierLoader) throws MalformedURLException, ClassNotFoundException
RMIClassLoaderSpi.loadClass(String,String,ClassLoader),
optionally verifying that the RFC3986 compliant
codebase URIs provide content integrity.
If verifyCodebaseIntegrity is true
and codebase is not null, then this
method invokes Security.verifyCodebaseIntegrity with codebase as
the first argument and verifierLoader as the
second argument (this invocation may be skipped if a previous
invocation of this method or loadProxyClass has already invoked
Security.verifyCodebaseIntegrity with the same
value of codebase and the same effective value of
verifierLoader as arguments without it throwing an
exception). If Security.verifyCodebaseIntegrity
throws a SecurityException, then this method
proceeds as if codebase were null.
If Security.verifyCodebaseIntegrity throws any
other exception, then this method throws that exception.
This method then invokes RMIClassLoaderSpi.loadClass with codebase as the
first argument (or null if in the previous step
Security.verifyCodebaseIntegrity was invoked and
it threw a SecurityException), name
as the second argument, and defaultLoader as the
third argument. If RMIClassLoaderSpi.loadClass
throws a ClassNotFoundException, then this method
throws a ClassNotFoundException; if
RMIClassLoaderSpi.loadClass throws any other
exception, then this method throws that exception; otherwise,
this method returns the Class returned by
RMIClassLoaderSpi.loadClass.
codebase - the list of URLs (separated by spaces) to load
the class from, or nullname - the name of the class to loaddefaultLoader - the class loader value (possibly
null) to pass as the defaultLoader
argument to RMIClassLoaderSpi.loadClassverifyCodebaseIntegrity - if true, verify
that the RFC3986 compliant codebase URIs provide content integrityverifierLoader - the class loader value (possibly
null) to pass to
Security.verifyCodebaseIntegrity, if
verifyCodebaseIntegrity is trueClass object representing the loaded
classMalformedURLException - if
Security.verifyCodebaseIntegrity or
RMIClassLoaderSpi.loadClass throws a
MalformedURLExceptionClassNotFoundException - if
RMIClassLoaderSpi.loadClass throws a
ClassNotFoundExceptionNullPointerException - if name is
nullpublic static Class<?> loadProxyClass(String codebase, String[] interfaceNames, ClassLoader defaultLoader, boolean verifyCodebaseIntegrity, ClassLoader verifierLoader) throws MalformedURLException, ClassNotFoundException
RMIClassLoaderSpi.loadProxyClass(String,String[],ClassLoader),
optionally verifying that the RFC3986 compliant
codebase URIs provide content integrity.
If verifyCodebaseIntegrity is true
and codebase is not null, then this
method invokes Security.verifyCodebaseIntegrity with codebase as
the first argument and verifierLoader as the
second argument (this invocation may be skipped if a previous
invocation of this method or loadClass has
already invoked Security.verifyCodebaseIntegrity
with the same value of codebase and the same
effective value of verifierLoader as arguments
without it throwing an exception). If
Security.verifyCodebaseIntegrity throws a
SecurityException, then this method proceeds as if
codebase were null. If
Security.verifyCodebaseIntegrity throws any other
exception, then this method throws that exception.
This method invokes RMIClassLoaderSpi.loadProxyClass(String,String[],ClassLoader)
with codebase as
the first argument (or null if in the previous
step Security.verifyCodebaseIntegrity was invoked
and it threw a SecurityException),
interfaceNames as the second argument, and
defaultLoader as the third argument. If
RMIClassLoaderSpi.loadProxyClass throws a
ClassNotFoundException, then this method throws a
ClassNotFoundException; if
RMIClassLoaderSpi.loadProxyClass throws any other
exception, then this method throws that exception; otherwise,
this method returns the Class returned by
RMIClassLoaderSpi.loadProxyClass.
codebase - the list of URLs (separated by spaces) to load
classes from, or nullinterfaceNames - the names of the interfaces for the proxy
class to implementdefaultLoader - the class loader value (possibly
null) to pass as the defaultLoader
argument to RMIClassLoader.loadProxyClassverifyCodebaseIntegrity - if true, verify
that the codebase URLs provide content integrityverifierLoader - the class loader value (possibly
null) to pass to
Security.verifyCodebaseIntegrity, if
verifyCodebaseIntegrity is trueClass object representing the loaded
dynamic proxy classMalformedURLException - if
Security.verifyCodebaseIntegrity or
RMIClassLoaderSpi.loadProxyClass throws a
MalformedURLExceptionClassNotFoundException - if
RMIClassLoaderSpi.loadProxyClass throws a
ClassNotFoundExceptionNullPointerException - if interfaceNames is
null or if any element of
interfaceNames is nullCopyright 2007-2013, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.