public class PreferredClassLoader extends org.apache.river.api.net.RFC3986URLClassLoader implements ClassAnnotation
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.
'#'
, 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.xThis 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-settingwhere 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-settingwhere 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 binary name is name-expression without
the ".class"
suffix and with each '/'
character replaced with a '.'
. It also matches any
class whose binary name starts with that same value followed by a
'$'
; this rule is intended to match nested classes
that have an enclosing class of that name, so that 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.
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. Given two non-wildcard entries, the entry with the longer name-expression is more specific (this rule is only significant when matching a class). The order of named preferred entries is insignificant.
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.
Constructor and Description |
---|
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. |
PreferredClassLoader(URL[] urls,
ClassLoader parent,
String exportAnnotation,
boolean requireDlPerm,
URLStreamHandlerFactory factory)
Creates a new
PreferredClassLoader that loads
classes and resources from the specified path of URLs,
delegates to the specified parent class loader, and uses the
specified URLStreamHandlerFactory when creating new URL
objects. |
Modifier and Type | Method and Description |
---|---|
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.
|
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.
|
Enumeration<URL> |
getResources(String name)
Gets an Enumeration of resources 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.
|
addURL, close, definePackage, findClass, findResource, findResources, getURLs, newInstance, newInstance
getResourceAsStream
defineClass, defineClass
clearAssertionStatus, defineClass, defineClass, defineClass, defineClass, findLibrary, findLoadedClass, findSystemClass, getClassLoadingLock, getPackage, getPackages, getParent, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, registerAsParallelCapable, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
public PreferredClassLoader(URL[] urls, ClassLoader parent, String exportAnnotation, boolean requireDlPerm)
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
.
urls
- the path of URLs to load classes and resources fromparent
- the parent class loader for delegationexportAnnotation
- 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
SecurityException
- if there is a security manager and an
invocation of its checkCreateClassLoader
method failspublic PreferredClassLoader(URL[] urls, ClassLoader parent, String exportAnnotation, boolean requireDlPerm, URLStreamHandlerFactory factory)
PreferredClassLoader
that loads
classes and resources from the specified path of URLs,
delegates to the specified parent class loader, and uses the
specified URLStreamHandlerFactory
when creating new URL
objects. This constructor passes factory
to the
superclass constructor that has a
URLStreamHandlerFactory
parameter.
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
.
urls
- the path of URLs to load classes and resources fromparent
- the parent class loader for delegationexportAnnotation
- 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
factory
- the URLStreamHandlerFactory
to use
when creating new URL objects, or null
SecurityException
- if there is a security manager and an
invocation of its checkCreateClassLoader
method failspublic static PreferredClassLoader newInstance(URL[] urls, ClassLoader parent, String exportAnnotation, boolean requireDlPerm)
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 constructors.
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
.
urls
- the path of URLs to load classes and resources fromparent
- the parent class loader for delegationexportAnnotation
- 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
PreferredClassLoader
instanceSecurityException
- if the current security context does
not have the permissions necessary to connect to all of the
URLs in urls
protected boolean isPreferredResource(String name, boolean isClass) throws IOException
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.
name
- the name of the class or resourceisClass
- true
if name
is a
binary class name, and false
if name
is the full path of a resourcetrue
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 loaderIOException
- 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 URLsprotected Class loadClass(String name, boolean resolve) throws ClassNotFoundException
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:
isPreferredResource
throws an
IOException
, then this method throws a
ClassNotFoundException
containing the
IOException
as its cause.
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.
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.
loadClass
in class ClassLoader
name
- the binary name of the class to loadresolve
- if true
, then resolveClass
will be invoked with the loaded class before
returningClassNotFoundException
- if the class could not be foundpublic URL getResource(String name)
PreferredClassLoader
implements this method as
follows:
This method invokes isPreferredResource
with name
as the first
argument and false
as the second argument:
isPreferredResource
throws an
IOException
, then this method returns
null
.
isPreferredResource
returns
true
, then this method invokes findResource
with name
and returns
the result.
isPreferredResource
returns
false
, then this method invokes the superclass
implementation of getResource
with name
and returns the result.
getResource
in class ClassLoader
name
- the name of the resource to getURL
for the resource, or
null
if the resource could not be foundpublic Enumeration<URL> getResources(String name) throws IOException
PreferredClassLoader
implements this method as
follows:
This method invokes isPreferredResource
with name
as the first
argument and false
as the second argument:
isPreferredResource
returns
true
, then this method invokes findResources
with name
and returns
the results.
isPreferredResource
returns
false
, then this method invokes the superclass
implementation of getResources
with name
and returns the result.
getResources
in class ClassLoader
name
- the name of the resource to getEnumeration
for the resource, the
Enumeration
is empty if the resource could not be foundan
- IOException if isPreferredResource throws an IOException.IOException
protected Package definePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)
definePackage
in class ClassLoader
public String getClassAnnotation()
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.
getClassAnnotation
in interface ClassAnnotation
null
protected PermissionCollection getPermissions(CodeSource codeSource)
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.
getPermissions
in class URLClassLoader
codeSource
- the CodeSource
to return the
permissions to be granted toCodeSource
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")