edu.emory.mathcs.util.classloader
Class URIClassLoader

java.lang.Object
  extended byjava.lang.ClassLoader
      extended byjava.security.SecureClassLoader
          extended byjava.net.URLClassLoader
              extended byedu.emory.mathcs.util.classloader.URIClassLoader

public class URIClassLoader
extends java.net.URLClassLoader

Equivalent of java.net.URLClassloader but without bugs related to ill-formed URLs and with customizable JAR caching policy. The standard URLClassLoader accepts URLs containing spaces and other characters which are forbidden in the URI syntax, according to the RFC 2396. As a workaround to this problem, Java escapes and un-escapes URLs in various arbitrary places; however, this is inconsistent and leads to numerous problems with URLs referring to local files with spaces in the path. SUN acknowledges the problem, but refuses to modify the behavior for compatibility reasons; see Java Bug Parade 4273532, 4466485.

Additionally, the JAR caching policy used by URLClassLoader is system-wide and inflexible: once downloaded JAR files are never re-downloaded, even if one creates a fresh instance of the class loader that happens to have the same URL in its search path. In fact, that policy is a security vulnerability: it is possible to crash any URL class loader, thus affecting potentially separate part of the system, by creating URL connection to one of the URLs of that class loader search path and closing the associated JAR file. See Java Bug Parade 4405789, 4388666, 4639900.

This class avoids these problems by 1) using URIs instead of URLs for the search path (thus enforcing strict syntax conformance and defining precise escaping semantics), and 2) using custom URLStreamHandler which ensures per-classloader JAR caching policy.

Version:
1.0
Author:
Dawid Kurzyniec
See Also:
File.toURL(), File.toURI()

Constructor Summary
URIClassLoader(java.net.URI[] uris)
          Creates URIClassLoader with the specified search path.
URIClassLoader(java.net.URI[] uris, java.lang.ClassLoader parent)
          Creates URIClassLoader with the specified search path and parent class loader.
URIClassLoader(java.net.URI[] uris, java.lang.ClassLoader parent, java.net.URLStreamHandler jarHandler)
          Creates URIClassLoader with the specified search path and parent class loader.
URIClassLoader(java.net.URI[] uris, java.net.URLStreamHandler jarHandler)
          Creates URIClassLoader with the specified search path.
 
Method Summary
protected  void addURI(java.net.URI uri)
          Add specified URI at the end of the search path.
protected  void addURL(java.net.URL url)
          Deprecated. use addURI
protected  java.lang.Class defineClass(java.lang.String name, ResourceHandle h)
           
protected  java.lang.Class findClass(java.lang.String name)
          Finds and loads the class with the specified name.
protected  java.lang.String findLibrary(java.lang.String libname)
          Returns the absolute path name of a native library.
 java.net.URL findResource(java.lang.String name)
          Finds the resource with the specified name.
 java.util.Enumeration findResources(java.lang.String name)
          Returns an Enumeration of URLs representing all of the resources having the specified name.
protected  ResourceHandle getClassHandle(java.lang.String name)
          Finds the ResourceHandle object for the class with the specified name.
protected  java.net.URLStreamHandler getJarHandler()
           
protected  ResourceHandle getLibraryHandle(java.lang.String name)
          Finds the ResourceHandle object for the native library with the specified name.
protected  ResourceHandle getResourceHandle(java.lang.String name)
          Finds the ResourceHandle object for the resource with the specified name.
protected  java.util.Enumeration getResourceHandles(java.lang.String name)
          Returns an Enumeration of ResourceHandle objects representing all of the resources having the specified name.
 java.net.URL[] getURLs()
           
 
Methods inherited from class java.net.URLClassLoader
definePackage, getPermissions, newInstance, newInstance
 
Methods inherited from class java.security.SecureClassLoader
defineClass
 
Methods inherited from class java.lang.ClassLoader
clearAssertionStatus, defineClass, defineClass, defineClass, definePackage, findLoadedClass, findSystemClass, getPackage, getPackages, getParent, getResource, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, loadClass, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

URIClassLoader

public URIClassLoader(java.net.URI[] uris)
Creates URIClassLoader with the specified search path.

Parameters:
uris - the search path

URIClassLoader

public URIClassLoader(java.net.URI[] uris,
                      java.net.URLStreamHandler jarHandler)
Creates URIClassLoader with the specified search path.

Parameters:
uris - the search path
jarHandler - stream handler for JAR files; implements caching policy

URIClassLoader

public URIClassLoader(java.net.URI[] uris,
                      java.lang.ClassLoader parent)
Creates URIClassLoader with the specified search path and parent class loader.

Parameters:
uris - the search path
parent - the parent class loader.

URIClassLoader

public URIClassLoader(java.net.URI[] uris,
                      java.lang.ClassLoader parent,
                      java.net.URLStreamHandler jarHandler)
Creates URIClassLoader with the specified search path and parent class loader.

Parameters:
uris - the search path
parent - the parent class loader.
jarHandler - stream handler for JAR files; implements caching policy
Method Detail

addURI

protected void addURI(java.net.URI uri)
Add specified URI at the end of the search path.

Parameters:
uri - the URI to add

addURL

protected void addURL(java.net.URL url)
Deprecated. use addURI

Add specified URL at the end of the search path.

Parameters:
url - the URL to add

getURLs

public java.net.URL[] getURLs()

findClass

protected java.lang.Class findClass(java.lang.String name)
                             throws java.lang.ClassNotFoundException
Finds and loads the class with the specified name.

Parameters:
name - the name of the class
Returns:
the resulting class
Throws:
java.lang.ClassNotFoundException - if the class could not be found

defineClass

protected java.lang.Class defineClass(java.lang.String name,
                                      ResourceHandle h)
                               throws java.io.IOException
Throws:
java.io.IOException

findResource

public java.net.URL findResource(java.lang.String name)
Finds the resource with the specified name.

Parameters:
name - the name of the resource
Returns:
a URL for the resource, or null if the resource could not be found.

findResources

public java.util.Enumeration findResources(java.lang.String name)
                                    throws java.io.IOException
Returns an Enumeration of URLs representing all of the resources having the specified name.

Parameters:
name - the resource name
Returns:
an Enumeration of URLs
Throws:
java.io.IOException - if an I/O exception occurs

findLibrary

protected java.lang.String findLibrary(java.lang.String libname)
Returns the absolute path name of a native library. The VM invokes this method to locate the native libraries that belong to classes loaded with this class loader. If this method returns null, the VM searches the library along the path specified as the java.library.path property. This method invoke getLibraryHandle(java.lang.String) method to find handle of this library. If the handle is found and its URL protocol is "file", the system-dependent absolute library file path is returned. Otherwise this method returns null.

Subclasses can override this method to provide specific approaches in library searching.

Parameters:
libname - the library name
Returns:
the absolute path of the native library
See Also:
System.loadLibrary(java.lang.String), System.mapLibraryName(java.lang.String)

getClassHandle

protected ResourceHandle getClassHandle(java.lang.String name)
Finds the ResourceHandle object for the class with the specified name. Unlike findClass(), this method does not load the class.

Parameters:
name - the name of the class
Returns:
the ResourceHandle of the class

getResourceHandle

protected ResourceHandle getResourceHandle(java.lang.String name)
Finds the ResourceHandle object for the resource with the specified name.

Parameters:
name - the name of the resource
Returns:
the ResourceHandle of the resource

getLibraryHandle

protected ResourceHandle getLibraryHandle(java.lang.String name)
Finds the ResourceHandle object for the native library with the specified name. The library name must be '/'-separated path. The last part of this path is substituted by its system-dependent mapping (using System.mapLibraryName(String) method). Next, the ResourceFinder is used to look for the library as it was ordinary resource.

Subclasses can override this method to provide specific approaches in library searching.

Parameters:
name - the name of the library
Returns:
the ResourceHandle of the library

getResourceHandles

protected java.util.Enumeration getResourceHandles(java.lang.String name)
Returns an Enumeration of ResourceHandle objects representing all of the resources having the specified name.

Parameters:
name - the name of the resource
Returns:
the ResourceHandle of the resource

getJarHandler

protected java.net.URLStreamHandler getJarHandler()