/* URLClassLoader.java --  ClassLoader that loads classes from one or more URLs
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.net;

import gnu.java.net.loader.FileURLLoader;
import gnu.java.net.loader.JarURLLoader;
import gnu.java.net.loader.RemoteURLLoader;
import gnu.java.net.loader.Resource;
import gnu.java.net.loader.URLLoader;
import gnu.java.net.loader.URLStreamHandlerCache;

import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.SecureClassLoader;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.Manifest;


/**
 * A secure class loader that can load classes and resources from
 * multiple locations.  Given an array of <code>URL</code>s this class
 * loader will retrieve classes and resources by fetching them from
 * possible remote locations.  Each <code>URL</code> is searched in
 * order in which it was added.  If the file portion of the
 * <code>URL</code> ends with a '/' character then it is interpreted
 * as a base directory, otherwise it is interpreted as a jar file from
 * which the classes/resources are resolved.
 *
 * <p>New instances can be created by two static
 * <code>newInstance()</code> methods or by three public
 * contructors. Both ways give the option to supply an initial array
 * of <code>URL</code>s and (optionally) a parent classloader (that is
 * different from the standard system class loader).</p>
 *
 * <p>Normally creating a <code>URLClassLoader</code> throws a
 * <code>SecurityException</code> if a <code>SecurityManager</code> is
 * installed and the <code>checkCreateClassLoader()</code> method does
 * not return true.  But the <code>newInstance()</code> methods may be
 * used by any code as long as it has permission to acces the given
 * <code>URL</code>s.  <code>URLClassLoaders</code> created by the
 * <code>newInstance()</code> methods also explicitly call the
 * <code>checkPackageAccess()</code> method of
 * <code>SecurityManager</code> if one is installed before trying to
 * load a class.  Note that only subclasses of
 * <code>URLClassLoader</code> can add new URLs after the
 * URLClassLoader had been created. But it is always possible to get
 * an array of all URLs that the class loader uses to resolve classes
 * and resources by way of the <code>getURLs()</code> method.</p>
 *
 * <p>Open issues:
 * <ul>
 *
 * <li>Should the URLClassLoader actually add the locations found in
 * the manifest or is this the responsibility of some other
 * loader/(sub)class?  (see <a
 * href="http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html">
 * Extension Mechanism Architecture - Bundles Extensions</a>)</li>
 *
 * <li>How does <code>definePackage()</code> and sealing work
 * precisely?</li>
 *
 * <li>We save and use the security context (when a created by
 * <code>newInstance()</code> but do we have to use it in more
 * places?</li>
 *
 * <li>The use of <code>URLStreamHandler</code>s has not been tested.</li>
 *
 * </ul>
 * </p>
 *
 * @since 1.2
 *
 * @author Mark Wielaard (mark@klomp.org)
 * @author Wu Gansha (gansha.wu@intel.com)
 */
public class URLClassLoader extends SecureClassLoader
{
  // Class Variables

  /**
   * A cache to store mappings between handler factory and its
   * private protocol handler cache (also a HashMap), so we can avoid
   * creating handlers each time the same protocol comes.
   */
  private static URLStreamHandlerCache factoryCache
    = new URLStreamHandlerCache();

  /**
   * The prefix for URL loaders.
   */
  private static final String URL_LOADER_PREFIX = "gnu.java.net.loader.Load_";

  // Instance variables

  /** Locations to load classes from */
  private final Vector urls = new Vector();

  /**
   * Store pre-parsed information for each url into this vector: each
   * element is a URL loader.  A jar file has its own class-path
   * attribute which adds to the URLs that will be searched, but this
   * does not add to the list of urls.
   */
  private final Vector urlinfos = new Vector();

  /** Factory used to get the protocol handlers of the URLs */
  private final URLStreamHandlerFactory factory;

  /**
   * The security context when created from <code>newInstance()</code>
   * or null when created through a normal constructor or when no
   * <code>SecurityManager</code> was installed.
   */
  private final AccessControlContext securityContext;

  // Helper classes

  /**
   * Creates a URLClassLoader that gets classes from the supplied URLs.
   * To determine if this classloader may be created the constructor of
   * the super class (<code>SecureClassLoader</code>) is called first, which
   * can throw a SecurityException. Then the supplied URLs are added
   * in the order given to the URLClassLoader which uses these URLs to
   * load classes and resources (after using the default parent ClassLoader).
   *
   * @param urls Locations that should be searched by this ClassLoader when
   * resolving Classes or Resources.
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @see SecureClassLoader
   */
  public URLClassLoader(URL[] urls) throws SecurityException
  {
    super();
    this.factory = null;
    this.securityContext = null;
    addURLs(urls);
  }

  /**
   * Creates a <code>URLClassLoader</code> that gets classes from the supplied
   * <code>URL</code>s.
   * To determine if this classloader may be created the constructor of
   * the super class (<code>SecureClassLoader</code>) is called first, which
   * can throw a SecurityException. Then the supplied URLs are added
   * in the order given to the URLClassLoader which uses these URLs to
   * load classes and resources (after using the supplied parent ClassLoader).
   * @param urls Locations that should be searched by this ClassLoader when
   * resolving Classes or Resources.
   * @param parent The parent class loader used before trying this class
   * loader.
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @exception SecurityException
   * @see SecureClassLoader
   */
  public URLClassLoader(URL[] urls, ClassLoader parent)
    throws SecurityException
  {
    super(parent);
    this.factory = null;
    this.securityContext = null;
    addURLs(urls);
  }

  // Package-private to avoid a trampoline constructor.
  /**
   * Package-private constructor used by the static
   * <code>newInstance(URL[])</code> method.  Creates an
   * <code>URLClassLoader</code> with the given parent but without any
   * <code>URL</code>s yet. This is used to bypass the normal security
   * check for creating classloaders, but remembers the security
   * context which will be used when defining classes.  The
   * <code>URL</code>s to load from must be added by the
   * <code>newInstance()</code> method in the security context of the
   * caller.
   *
   * @param securityContext the security context of the unprivileged code.
   */
  URLClassLoader(ClassLoader parent, AccessControlContext securityContext)
  {
    super(parent);
    this.factory = null;
    this.securityContext = securityContext;
  }

  /**
   * Creates a URLClassLoader that gets classes from the supplied URLs.
   * To determine if this classloader may be created the constructor of
   * the super class (<CODE>SecureClassLoader</CODE>) is called first, which
   * can throw a SecurityException. Then the supplied URLs are added
   * in the order given to the URLClassLoader which uses these URLs to
   * load classes and resources (after using the supplied parent ClassLoader).
   * It will use the supplied <CODE>URLStreamHandlerFactory</CODE> to get the
   * protocol handlers of the supplied URLs.
   * @param urls Locations that should be searched by this ClassLoader when
   * resolving Classes or Resources.
   * @param parent The parent class loader used before trying this class
   * loader.
   * @param factory Used to get the protocol handler for the URLs.
   * @exception SecurityException if the SecurityManager disallows the
   * creation of a ClassLoader.
   * @exception SecurityException
   * @see SecureClassLoader
   */
  public URLClassLoader(URL[] urls, ClassLoader parent,
                        URLStreamHandlerFactory factory)
    throws SecurityException
  {
    super(parent);
    this.securityContext = null;
    this.factory = factory;
    addURLs(urls);

    // If this factory is still not in factoryCache, add it.
    factoryCache.add(factory);
  }

  // Methods

  /**
   * Adds a new location to the end of the internal URL store.
   * @param newUrl the location to add
   */
  protected void addURL(URL newUrl)
  {
    urls.add(newUrl);
    addURLImpl(newUrl);
  }

  private void addURLImpl(URL newUrl)
  {
    synchronized (this)
      {
        if (newUrl == null)
          return; // Silently ignore...

	// Reset the toString() value.
	thisString = null;

        // Create a loader for this URL.
        URLLoader loader = null;
        String file = newUrl.getFile();
        String protocol = newUrl.getProtocol();

        // If we have a file: URL, we want to make it absolute
        // here, before we decide whether it is really a jar.
        URL absoluteURL;
        if ("file".equals (protocol))
          {
            File dir = new File(file);
            URL absUrl;
            try
              {
                absoluteURL = dir.getCanonicalFile().toURL();
              }
            catch (IOException ignore)
              {
                try
                  {
                    absoluteURL = dir.getAbsoluteFile().toURL();
                  }
                catch (MalformedURLException _)
                  {
                    // This really should not happen.
                    absoluteURL = newUrl;
                  }
              }
          }
        else
          {
            // This doesn't hurt, and it simplifies the logic a
            // little.
            absoluteURL = newUrl;
          }

        // First see if we can find a handler with the correct name.
        try
          {
            Class handler = Class.forName(URL_LOADER_PREFIX + protocol);
            Class[] argTypes = new Class[] { URLClassLoader.class,
                                             URLStreamHandlerCache.class,
                                             URLStreamHandlerFactory.class,
                                             URL.class,
                                             URL.class };
            Constructor k = handler.getDeclaredConstructor(argTypes);
            loader
              = (URLLoader) k.newInstance(new Object[] { this,
                                                         factoryCache,
                                                         factory,
                                                         newUrl,
                                                         absoluteURL });
          }
        catch (ClassNotFoundException ignore)
          {
            // Fall through.
          }
        catch (NoSuchMethodException nsme)
          {
            // Programming error in the class library.
            InternalError vme
              = new InternalError("couldn't find URLLoader constructor");
            vme.initCause(nsme);
            throw vme;
          }
        catch (InstantiationException inste)
          {
            // Programming error in the class library.
            InternalError vme
              = new InternalError("couldn't instantiate URLLoader");
            vme.initCause(inste);
            throw vme;
          }
        catch (InvocationTargetException ite)
          {
            // Programming error in the class library.
            InternalError vme
              = new InternalError("error instantiating URLLoader");
            vme.initCause(ite);
            throw vme;
          }
        catch (IllegalAccessException illae)
          {
            // Programming error in the class library.
            InternalError vme
              = new InternalError("invalid access to URLLoader");
            vme.initCause(illae);
            throw vme;
          }

        if (loader == null)
          {
            // If it is not a directory, use the jar loader.
            if (! (file.endsWith("/") || file.endsWith(File.separator)))
              loader = new JarURLLoader(this, factoryCache, factory,
                                        newUrl, absoluteURL);
            else if ("file".equals(protocol))
              loader = new FileURLLoader(this, factoryCache, factory,
                                         newUrl, absoluteURL);
            else
              loader = new RemoteURLLoader(this, factoryCache, factory,
                                           newUrl);
          }

	urlinfos.add(loader);
	ArrayList extra = loader.getClassPath();
        if (extra != null)
          urlinfos.addAll(extra);
      }
  }

  /**
   * Adds an array of new locations to the end of the internal URL
   * store.  Called from the the constructors. Should not call to the
   * protected addURL() method since that can be overridden and
   * subclasses are not yet in a good state at this point.
   * jboss 4.0.3 for example depends on this.
   *
   * @param newUrls the locations to add
   */
  private void addURLs(URL[] newUrls)
  {
    for (int i = 0; i < newUrls.length; i++)
      {
	urls.add(newUrls[i]);
	addURLImpl(newUrls[i]);
      }
  }

  /**
   * Look in both Attributes for a given value.  The first Attributes
   * object, if not null, has precedence.
   */
  private String getAttributeValue(Attributes.Name name, Attributes first,
				   Attributes second)
  {
    String result = null;
    if (first != null)
      result = first.getValue(name);
    if (result == null)
      result = second.getValue(name);
    return result;
  }

  /**
   * Defines a Package based on the given name and the supplied manifest
   * information. The manifest indicates the title, version and
   * vendor information of the specification and implementation and whether the
   * package is sealed. If the Manifest indicates that the package is sealed
   * then the Package will be sealed with respect to the supplied URL.
   *
   * @param name The name of the package
   * @param manifest The manifest describing the specification,
   * implementation and sealing details of the package
   * @param url the code source url to seal the package
   * @return the defined Package
   * @throws IllegalArgumentException If this package name already exists
   * in this class loader
   */
  protected Package definePackage(String name, Manifest manifest, URL url)
    throws IllegalArgumentException
  {
    // Compute the name of the package as it may appear in the
    // Manifest.
    StringBuffer xform = new StringBuffer(name);
    for (int i = xform.length () - 1; i >= 0; --i)
      if (xform.charAt(i) == '.')
	xform.setCharAt(i, '/');
    xform.append('/');
    String xformName = xform.toString();

    Attributes entryAttr = manifest.getAttributes(xformName);
    Attributes attr = manifest.getMainAttributes();

    String specTitle
      = getAttributeValue(Attributes.Name.SPECIFICATION_TITLE,
			  entryAttr, attr);
    String specVersion
      = getAttributeValue(Attributes.Name.SPECIFICATION_VERSION,
			  entryAttr, attr);
    String specVendor
      = getAttributeValue(Attributes.Name.SPECIFICATION_VENDOR,
			  entryAttr, attr);
    String implTitle
      = getAttributeValue(Attributes.Name.IMPLEMENTATION_TITLE,
			  entryAttr, attr);
    String implVersion
      = getAttributeValue(Attributes.Name.IMPLEMENTATION_VERSION,
			  entryAttr, attr);
    String implVendor
      = getAttributeValue(Attributes.Name.IMPLEMENTATION_VENDOR,
			  entryAttr, attr);

    // Look if the Manifest indicates that this package is sealed
    // XXX - most likely not completely correct!
    // Shouldn't we also check the sealed attribute of the complete jar?
    // http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html#bundled
    // But how do we get that jar manifest here?
    String sealed = attr.getValue(Attributes.Name.SEALED);
    if ("false".equals(sealed))
      // make sure that the URL is null so the package is not sealed
      url = null;

    return definePackage(name,
			 specTitle, specVendor, specVersion,
			 implTitle, implVendor, implVersion,
			 url);
  }

  /**
   * Finds (the first) class by name from one of the locations. The locations
   * are searched in the order they were added to the URLClassLoader.
   *
   * @param className the classname to find
   * @exception ClassNotFoundException when the class could not be found or
   * loaded
   * @return a Class object representing the found class
   */
  protected Class findClass(final String className)
    throws ClassNotFoundException
  {
    // Just try to find the resource by the (almost) same name
    String resourceName = className.replace('.', '/') + ".class";
    int max = urlinfos.size();
    Resource resource = null;
    for (int i = 0; i < max && resource == null; i++)
      {
        URLLoader loader = (URLLoader)urlinfos.elementAt(i);
        if (loader == null)
          continue;

        Class k = loader.getClass(className);
        if (k != null)
          return k;

        resource = loader.getResource(resourceName);
      }
    if (resource == null)
      throw new ClassNotFoundException(className + " not found in " + this);

    // Try to read the class data, create the CodeSource, Package and
    // construct the class (and watch out for those nasty IOExceptions)
    try
      {
	byte[] data;
	InputStream in = resource.getInputStream();
	try
	  {
	    int length = resource.getLength();
	    if (length != -1)
	      {
		// We know the length of the data.
		// Just try to read it in all at once
		data = new byte[length];
		int pos = 0;
		while (length - pos > 0)
		  {
		    int len = in.read(data, pos, length - pos);
		    if (len == -1)
		      throw new EOFException("Not enough data reading from: "
					     + in);
		    pos += len;
		  }
	      }
	    else
	      {
		// We don't know the data length.
		// Have to read it in chunks.
		ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
		byte[] b = new byte[4096];
		int l = 0;
		while (l != -1)
		  {
		    l = in.read(b);
		    if (l != -1)
		      out.write(b, 0, l);
		  }
		data = out.toByteArray();
	      }
	  }
	finally
	  {
	    in.close();
	  }
	final byte[] classData = data;

        // Now get the CodeSource
        final CodeSource source = resource.getCodeSource();

        // Find out package name
        String packageName = null;
        int lastDot = className.lastIndexOf('.');
        if (lastDot != -1)
          packageName = className.substring(0, lastDot);

        if (packageName != null && getPackage(packageName) == null)
          {
            // define the package
            Manifest manifest = resource.getLoader().getManifest();
            if (manifest == null)
              definePackage(packageName, null, null, null, null, null, null,
                            null);
            else
              definePackage(packageName, manifest,
                            resource.getLoader().getBaseURL());
          }

        // And finally construct the class!
        SecurityManager sm = System.getSecurityManager();
        Class result = null;
        if (sm != null && securityContext != null)
          {
            result = (Class)AccessController.doPrivileged
              (new PrivilegedAction()
                {
                  public Object run()
                  {
                    return defineClass(className, classData,
                                       0, classData.length,
                                       source);
                  }
                }, securityContext);
          }
        else
          result = defineClass(className, classData, 0, classData.length, source);

        // Avoid NullPointerExceptions.
        Certificate[] resourceCertificates = resource.getCertificates();
        if(resourceCertificates != null)
          super.setSigners(result, resourceCertificates);
        
        return result;
      }
    catch (IOException ioe)
      {
	ClassNotFoundException cnfe;
	cnfe = new ClassNotFoundException(className + " not found in " + this);
	cnfe.initCause(ioe);
	throw cnfe;
      }
  }
  
  // Cached String representation of this URLClassLoader
  private String thisString;
  
  /**
   * Returns a String representation of this URLClassLoader giving the
   * actual Class name, the URLs that are searched and the parent
   * ClassLoader.
   */
  public String toString()
  {
    synchronized (this)
      {
	if (thisString == null)
	  {
	    StringBuffer sb = new StringBuffer();
	    sb.append(this.getClass().getName());
	    sb.append("{urls=[" );
	    URL[] thisURLs = getURLs();
	    for (int i = 0; i < thisURLs.length; i++)
	      {
		sb.append(thisURLs[i]);
		if (i < thisURLs.length - 1)
		  sb.append(',');
	      }
	    sb.append(']');
	    sb.append(", parent=");
	    sb.append(getParent());
	    sb.append('}');
	    thisString = sb.toString();
	  }
	return thisString;
      }
  }

  /**
   * Finds the first occurrence of a resource that can be found. The locations
   * are searched in the order they were added to the URLClassLoader.
   *
   * @param resourceName the resource name to look for
   * @return the URLResource for the resource if found, null otherwise
   */
  private Resource findURLResource(String resourceName)
  {
    int max = urlinfos.size();
    for (int i = 0; i < max; i++)
      {
        URLLoader loader = (URLLoader) urlinfos.elementAt(i);
        if (loader == null)
          continue;

        Resource resource = loader.getResource(resourceName);
        if (resource != null)
          return resource;
      }
    return null;
  }

  /**
   * Finds the first occurrence of a resource that can be found.
   *
   * @param resourceName the resource name to look for
   * @return the URL if found, null otherwise
   */
  public URL findResource(String resourceName)
  {
    Resource resource = findURLResource(resourceName);
    if (resource != null)
      return resource.getURL();

    // Resource not found
    return null;
  }

  /**
   * Finds all the resources with a particular name from all the locations.
   *
   * @param resourceName the name of the resource to lookup
   * @return a (possible empty) enumeration of URLs where the resource can be
   * found
   * @exception IOException when an error occurs accessing one of the
   * locations
   */
  public Enumeration findResources(String resourceName)
    throws IOException
  {
    Vector resources = new Vector();
    int max = urlinfos.size();
    for (int i = 0; i < max; i++)
      {
        URLLoader loader = (URLLoader) urlinfos.elementAt(i);
        Resource resource = loader.getResource(resourceName);
        if (resource != null)
          resources.add(resource.getURL());
      }
    return resources.elements();
  }

  /**
   * Returns the permissions needed to access a particular code
   * source.  These permissions includes those returned by
   * <code>SecureClassLoader.getPermissions()</code> and the actual
   * permissions to access the objects referenced by the URL of the
   * code source.  The extra permissions added depend on the protocol
   * and file portion of the URL in the code source. If the URL has
   * the "file" protocol ends with a '/' character then it must be a
   * directory and a file Permission to read everything in that
   * directory and all subdirectories is added. If the URL had the
   * "file" protocol and doesn't end with a '/' character then it must
   * be a normal file and a file permission to read that file is
   * added. If the <code>URL</code> has any other protocol then a
   * socket permission to connect and accept connections from the host
   * portion of the URL is added.
   *
   * @param source The codesource that needs the permissions to be accessed
   * @return the collection of permissions needed to access the code resource
   * @see java.security.SecureClassLoader#getPermissions(CodeSource)
   */
  protected PermissionCollection getPermissions(CodeSource source)
  {
    // XXX - This implementation does exactly as the Javadoc describes.
    // But maybe we should/could use URLConnection.getPermissions()?
    // First get the permissions that would normally be granted
    PermissionCollection permissions = super.getPermissions(source);

    // Now add any extra permissions depending on the URL location.
    URL url = source.getLocation();
    String protocol = url.getProtocol();
    if (protocol.equals("file"))
      {
        String file = url.getFile();

        // If the file end in / it must be an directory.
        if (file.endsWith("/") || file.endsWith(File.separator))
          {
            // Grant permission to read everything in that directory and
            // all subdirectories.
            permissions.add(new FilePermission(file + "-", "read"));
          }
        else
          {
            // It is a 'normal' file.
            // Grant permission to access that file.
            permissions.add(new FilePermission(file, "read"));
          }
      }
    else
      {
        // Grant permission to connect to and accept connections from host
        String host = url.getHost();
        if (host != null)
          permissions.add(new SocketPermission(host, "connect,accept"));
      }

    return permissions;
  }

  /**
   * Returns all the locations that this class loader currently uses the
   * resolve classes and resource. This includes both the initially supplied
   * URLs as any URLs added later by the loader.
   * @return All the currently used URLs
   */
  public URL[] getURLs()
  {
    return (URL[]) urls.toArray(new URL[urls.size()]);
  }

  /**
   * Creates a new instance of a <code>URLClassLoader</code> that gets
   * classes from the supplied <code>URL</code>s. This class loader
   * will have as parent the standard system class loader.
   *
   * @param urls the initial URLs used to resolve classes and
   * resources
   *
   * @return the class loader
   *
   * @exception SecurityException when the calling code does not have
   * permission to access the given <code>URL</code>s
   */
  public static URLClassLoader newInstance(URL[] urls)
    throws SecurityException
  {
    return newInstance(urls, null);
  }

  /**
   * Creates a new instance of a <code>URLClassLoader</code> that gets
   * classes from the supplied <code>URL</code>s and with the supplied
   * loader as parent class loader.
   *
   * @param urls the initial URLs used to resolve classes and
   * resources
   * @param parent the parent class loader
   *
   * @return the class loader
   *
   * @exception SecurityException when the calling code does not have
   * permission to access the given <code>URL</code>s
   */
  public static URLClassLoader newInstance(URL[] urls, final ClassLoader parent)
    throws SecurityException
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm == null)
      return new URLClassLoader(urls, parent);
    else
      {
        final Object securityContext = sm.getSecurityContext();

        // XXX - What to do with anything else then an AccessControlContext?
        if (! (securityContext instanceof AccessControlContext))
          throw new SecurityException("securityContext must be AccessControlContext: "
                                      + securityContext);

        URLClassLoader loader =
          (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction()
              {
                public Object run()
                {
                  return new URLClassLoader(parent,
                                            (AccessControlContext) securityContext);
                }
              });
        loader.addURLs(urls);
        return loader;
      }
  }
}
