URLClassLoaderpublic class URLClassLoader extends SecureClassLoader This class loader is used to load classes and resources from a search
path of URLs referring to both JAR files and directories. Any URL that
ends with a '/' is assumed to refer to a directory. Otherwise, the URL
is assumed to refer to a JAR file which will be opened as needed.
The AccessControlContext of the thread that created the instance of
URLClassLoader will be used when subsequently loading classes and
resources.
The classes that are loaded are by default granted permission only to
access the URLs specified when the URLClassLoader was created. |
Fields Summary |
---|
private sun.misc.URLClassPath | ucp | private AccessControlContext | acc |
Constructors Summary |
---|
public URLClassLoader(URL[] urls, ClassLoader parent)Constructs a new URLClassLoader for the given URLs. The URLs will be
searched in the order specified for classes and resources after first
searching in the specified parent class loader. Any URL that ends with
a '/' is assumed to refer to a directory. Otherwise, the URL is assumed
to refer to a JAR file which will be downloaded and opened as needed.
If there is a security manager, this method first
calls the security manager's checkCreateClassLoader method
to ensure creation of a class loader is allowed.
super(parent);
// this is to make the stack depth consistent with 1.1
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
ucp = new URLClassPath(urls);
acc = AccessController.getContext();
| public URLClassLoader(URL[] urls)Constructs a new URLClassLoader for the specified URLs using the
default delegation parent ClassLoader . The URLs will
be searched in the order specified for classes and resources after
first searching in the parent class loader. Any URL that ends with
a '/' is assumed to refer to a directory. Otherwise, the URL is
assumed to refer to a JAR file which will be downloaded and opened
as needed.
If there is a security manager, this method first
calls the security manager's checkCreateClassLoader method
to ensure creation of a class loader is allowed.
super();
// this is to make the stack depth consistent with 1.1
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
ucp = new URLClassPath(urls);
acc = AccessController.getContext();
| public URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory)Constructs a new URLClassLoader for the specified URLs, parent
class loader, and URLStreamHandlerFactory. The parent argument
will be used as the parent class loader for delegation. The
factory argument will be used as the stream handler factory to
obtain protocol handlers when creating new URLs.
If there is a security manager, this method first
calls the security manager's checkCreateClassLoader method
to ensure creation of a class loader is allowed.
super(parent);
// this is to make the stack depth consistent with 1.1
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
ucp = new URLClassPath(urls, factory);
acc = AccessController.getContext();
|
Methods Summary |
---|
protected void | addURL(java.net.URL url)Appends the specified URL to the list of URLs to search for
classes and resources.
ucp.addURL(url);
| private java.lang.Class | defineClass(java.lang.String name, sun.misc.Resource res)
int i = name.lastIndexOf('.");
URL url = res.getCodeSourceURL();
if (i != -1) {
String pkgname = name.substring(0, i);
// Check if package already loaded.
Package pkg = getPackage(pkgname);
Manifest man = res.getManifest();
if (pkg != null) {
// Package found, so check package sealing.
if (pkg.isSealed()) {
// Verify that code source URL is the same.
if (!pkg.isSealed(url)) {
throw new SecurityException(
"sealing violation: package " + pkgname + " is sealed");
}
} else {
// Make sure we are not attempting to seal the package
// at this code source URL.
if ((man != null) && isSealed(pkgname, man)) {
throw new SecurityException(
"sealing violation: can't seal package " + pkgname +
": already loaded");
}
}
} else {
if (man != null) {
definePackage(pkgname, man, url);
} else {
definePackage(pkgname, null, null, null, null, null, null, null);
}
}
}
// Now read the class bytes and define the class
java.nio.ByteBuffer bb = res.getByteBuffer();
if (bb != null) {
// Use (direct) ByteBuffer:
CodeSigner[] signers = res.getCodeSigners();
CodeSource cs = new CodeSource(url, signers);
return defineClass(name, bb, cs);
} else {
byte[] b = res.getBytes();
// must read certificates AFTER reading bytes.
CodeSigner[] signers = res.getCodeSigners();
CodeSource cs = new CodeSource(url, signers);
return defineClass(name, b, 0, b.length, cs);
}
| protected java.lang.Package | definePackage(java.lang.String name, java.util.jar.Manifest man, java.net.URL url)Defines a new package by name in this ClassLoader. The attributes
contained in the specified Manifest will be used to obtain package
version and sealing information. For sealed packages, the additional
URL specifies the code source URL from which the package was loaded.
String path = name.replace('.", '/").concat("/");
String specTitle = null, specVersion = null, specVendor = null;
String implTitle = null, implVersion = null, implVendor = null;
String sealed = null;
URL sealBase = null;
Attributes attr = man.getAttributes(path);
if (attr != null) {
specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
sealed = attr.getValue(Name.SEALED);
}
attr = man.getMainAttributes();
if (attr != null) {
if (specTitle == null) {
specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
}
if (specVersion == null) {
specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
}
if (specVendor == null) {
specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
}
if (implTitle == null) {
implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
}
if (implVersion == null) {
implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
}
if (implVendor == null) {
implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
}
if (sealed == null) {
sealed = attr.getValue(Name.SEALED);
}
}
if ("true".equalsIgnoreCase(sealed)) {
sealBase = url;
}
return definePackage(name, specTitle, specVersion, specVendor,
implTitle, implVersion, implVendor, sealBase);
| protected java.lang.Class | findClass(java.lang.String name)Finds and loads the class with the specified name from the URL search
path. Any URLs referring to JAR files are loaded and opened as needed
until the class is found.
try {
return (Class)
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws ClassNotFoundException {
String path = name.replace('.", '/").concat(".class");
Resource res = ucp.getResource(path, false);
if (res != null) {
try {
return defineClass(name, res);
} catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
} else {
throw new ClassNotFoundException(name);
}
}
}, acc);
} catch (java.security.PrivilegedActionException pae) {
throw (ClassNotFoundException) pae.getException();
}
| public java.net.URL | findResource(java.lang.String name)Finds the resource with the specified name on the URL search path.
/*
* The same restriction to finding classes applies to resources
*/
URL url =
(URL) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return ucp.findResource(name, true);
}
}, acc);
return url != null ? ucp.checkURL(url) : null;
| public java.util.Enumeration | findResources(java.lang.String name)Returns an Enumeration of URLs representing all of the resources
on the URL search path having the specified name.
final Enumeration e = ucp.findResources(name, true);
return new Enumeration<URL>() {
private URL url = null;
private boolean next() {
if (url != null) {
return true;
}
do {
URL u = (URL)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
if (!e.hasMoreElements())
return null;
return e.nextElement();
}
}, acc);
if (u == null)
break;
url = ucp.checkURL(u);
} while (url == null);
return url != null;
}
public URL nextElement() {
if (!next()) {
throw new NoSuchElementException();
}
URL u = url;
url = null;
return u;
}
public boolean hasMoreElements() {
return next();
}
};
| protected java.security.PermissionCollection | getPermissions(java.security.CodeSource codesource)Returns the permissions for the given codesource object.
The implementation of this method first calls super.getPermissions
and then adds permissions based on the URL of the codesource.
If the protocol is "file"
and the path specifies a file, then permission to read that
file is granted. If protocol is "file" and the path is
a directory, permission is granted to read all files
and (recursively) all files and subdirectories contained in
that directory.
If the protocol is not "file", then
to connect to and accept connections from the URL's host is granted.
PermissionCollection perms = super.getPermissions(codesource);
URL url = codesource.getLocation();
Permission p;
URLConnection urlConnection;
try {
urlConnection = url.openConnection();
p = urlConnection.getPermission();
} catch (java.io.IOException ioe) {
p = null;
urlConnection = null;
}
if (p instanceof FilePermission) {
// if the permission has a separator char on the end,
// it means the codebase is a directory, and we need
// to add an additional permission to read recursively
String path = p.getName();
if (path.endsWith(File.separator)) {
path += "-";
p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
}
} else if ((p == null) && (url.getProtocol().equals("file"))) {
String path = url.getFile().replace('/", File.separatorChar);
path = ParseUtil.decode(path);
if (path.endsWith(File.separator))
path += "-";
p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
} else {
URL locUrl = url;
if (urlConnection instanceof JarURLConnection) {
locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
}
String host = locUrl.getHost();
if (host == null)
host = "localhost";
p = new SocketPermission(host,
SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION);
}
// make sure the person that created this class loader
// would have this permission
if (p != null) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
final Permission fp = p;
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() throws SecurityException {
sm.checkPermission(fp);
return null;
}
}, acc);
}
perms.add(p);
}
return perms;
| public java.net.URL[] | getURLs()Returns the search path of URLs for loading classes and resources.
This includes the original list of URLs specified to the constructor,
along with any URLs subsequently appended by the addURL() method.
return ucp.getURLs();
| private boolean | isSealed(java.lang.String name, java.util.jar.Manifest man)
String path = name.replace('.", '/").concat("/");
Attributes attr = man.getAttributes(path);
String sealed = null;
if (attr != null) {
sealed = attr.getValue(Name.SEALED);
}
if (sealed == null) {
if ((attr = man.getMainAttributes()) != null) {
sealed = attr.getValue(Name.SEALED);
}
}
return "true".equalsIgnoreCase(sealed);
| public static java.net.URLClassLoader | newInstance(java.net.URL[] urls, java.lang.ClassLoader parent)Creates a new instance of URLClassLoader for the specified
URLs and parent class loader. If a security manager is
installed, the loadClass method of the URLClassLoader
returned by this method will invoke the
SecurityManager.checkPackageAccess method before
loading the class.
// Save the caller's context
AccessControlContext acc = AccessController.getContext();
// Need a privileged block to create the class loader
URLClassLoader ucl =
(URLClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return new FactoryURLClassLoader(urls, parent);
}
});
// Now set the context on the loader using the one we saved,
// not the one inside the privileged block...
ucl.acc = acc;
return ucl;
| public static java.net.URLClassLoader | newInstance(java.net.URL[] urls)Creates a new instance of URLClassLoader for the specified
URLs and default parent class loader. If a security manager is
installed, the loadClass method of the URLClassLoader
returned by this method will invoke the
SecurityManager.checkPackageAccess before
loading the class.
// Save the caller's context
AccessControlContext acc = AccessController.getContext();
// Need a privileged block to create the class loader
URLClassLoader ucl = (URLClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return new FactoryURLClassLoader(urls);
}
});
// Now set the context on the loader using the one we saved,
// not the one inside the privileged block...
ucl.acc = acc;
return ucl;
|
|