--- /home/cpdev/src/classpath/java/lang/ClassLoader.java	2005-07-02 21:03:31.000000000 +0000
+++ java/lang/ClassLoader.java	2005-06-30 05:34:38.000000000 +0000
@@ -38,26 +38,19 @@
 
 package java.lang;
 
-import gnu.classpath.SystemProperties;
-import gnu.classpath.VMStackWalker;
 import gnu.java.util.DoubleEnumeration;
 import gnu.java.util.EmptyEnumeration;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.lang.reflect.Constructor;
 import java.net.URL;
-import java.net.URLClassLoader;
 import java.security.CodeSource;
 import java.security.PermissionCollection;
 import java.security.Policy;
 import java.security.ProtectionDomain;
-import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.StringTokenizer;
 
 /**
  * The ClassLoader is a way of customizing the way Java gets its classes
@@ -86,8 +79,8 @@
  * <p>The bootstrap classloader in GNU Classpath is implemented as a couple of
  * static (native) methods on the package private class
  * <code>java.lang.VMClassLoader</code>, the system classloader is an
- * anonymous inner class of ClassLoader and a subclass of
- * <code>java.net.URLClassLoader</code>.
+ * instance of <code>gnu.java.lang.SystemClassLoader</code>
+ * (which is a subclass of <code>java.net.URLClassLoader</code>).
  *
  * <p>Users of a <code>ClassLoader</code> will normally just use the methods
  * <ul>
@@ -152,72 +145,27 @@
    */
   private final boolean initialized;
 
-  static class StaticData
-  {
-    /**
-     * The System Class Loader (a.k.a. Application Class Loader). The one
-     * returned by ClassLoader.getSystemClassLoader.
-     */
-    static final ClassLoader systemClassLoader =
-                              VMClassLoader.getSystemClassLoader();
-    static
-    {
-      // Find out if we have to install a default security manager. Note that
-      // this is done here because we potentially need the system class loader
-      // to load the security manager and note also that we don't need the
-      // security manager until the system class loader is created.
-      // If the runtime chooses to use a class loader that doesn't have the
-      // system class loader as its parent, it is responsible for setting
-      // up a security manager before doing so.
-      String secman = SystemProperties.getProperty("java.security.manager");
-      if (secman != null && SecurityManager.current == null)
-        {
-          if (secman.equals("") || secman.equals("default"))
-	    {
-	      SecurityManager.current = new SecurityManager();
-	    }
-	  else
-	    {
-	      try
-	        {
-	  	  Class cl = Class.forName(secman, false, StaticData.systemClassLoader);
-		  SecurityManager.current = (SecurityManager)cl.newInstance();
-	        }
-	      catch (Exception x)
-	        {
-		  throw (InternalError)
-		      new InternalError("Unable to create SecurityManager")
-		  	  .initCause(x);
-	        }
-	    }
-        }
-    }
-
-    /**
-     * The default protection domain, used when defining a class with a null
-     * parameter for the domain.
-     */
-    static final ProtectionDomain defaultProtectionDomain;
-    static
-    {
-        CodeSource cs = new CodeSource(null, null);
-        PermissionCollection perm = Policy.getPolicy().getPermissions(cs);
-        defaultProtectionDomain = new ProtectionDomain(cs, perm);
-    }
-    /**
-     * The command-line state of the package assertion status overrides. This
-     * map is never modified, so it does not need to be synchronized.
-     */
-    // Package visible for use by Class.
-    static final Map systemPackageAssertionStatus
-      = VMClassLoader.packageAssertionStatus();
-    /**
-     * The command-line state of the class assertion status overrides. This
-     * map is never modified, so it does not need to be synchronized.
-     */
-    // Package visible for use by Class.
-    static final Map systemClassAssertionStatus
-      = VMClassLoader.classAssertionStatus();
+  /**
+   * System/Application classloader: defaults to an instance of
+   * gnu.java.lang.SystemClassLoader, unless the first invocation of
+   * getSystemClassLoader loads another class loader because of the
+   * java.system.class.loader property. The initialization of this field
+   * is somewhat circular - getSystemClassLoader() checks whether this
+   * field is null in order to bypass a security check.
+   */
+  static final ClassLoader systemClassLoader =
+    VMClassLoader.getSystemClassLoader();
+
+  /**
+   * The default protection domain, used when defining a class with a null
+   * paramter for the domain.
+   */
+  static final ProtectionDomain defaultProtectionDomain;
+  static
+  {
+    CodeSource cs = new CodeSource(null, null);
+    PermissionCollection perm = Policy.getPolicy().getPermissions(cs);
+    defaultProtectionDomain = new ProtectionDomain(cs, perm);
   }
 
   /**
@@ -228,6 +176,14 @@
   boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus();
 
   /**
+   * The command-line state of the package assertion status overrides. This
+   * map is never modified, so it does not need to be synchronized.
+   */
+  // Package visible for use by Class.
+  static final Map systemPackageAssertionStatus
+    = VMClassLoader.packageAssertionStatus();
+
+  /**
    * The map of package assertion status overrides, or null if no package
    * overrides have been specified yet. The values of the map should be
    * Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented
@@ -237,6 +193,14 @@
   Map packageAssertionStatus;
 
   /**
+   * The command-line state of the class assertion status overrides. This
+   * map is never modified, so it does not need to be synchronized.
+   */
+  // Package visible for use by Class.
+  static final Map systemClassAssertionStatus
+    = VMClassLoader.classAssertionStatus();
+
+  /**
    * The map of class assertion status overrides, or null if no class
    * overrides have been specified yet. The values of the map should be
    * Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this
@@ -246,11 +210,6 @@
   Map classAssertionStatus;
 
   /**
-   * VM private data.
-   */
-  transient Object vmdata;
-
-  /**
    * Create a new ClassLoader with as parent the system classloader. There
    * may be a security check for <code>checkCreateClassLoader</code>.
    *
@@ -258,7 +217,7 @@
    */
   protected ClassLoader() throws SecurityException
   {
-    this(StaticData.systemClassLoader);
+    this(systemClassLoader);
   }
 
   /**
@@ -278,7 +237,7 @@
   protected ClassLoader(ClassLoader parent)
   {
     // May we create a new classloader?
-    SecurityManager sm = SecurityManager.current;
+    SecurityManager sm = System.getSecurityManager();
     if (sm != null)
       sm.checkCreateClassLoader();
     this.parent = parent;
@@ -301,6 +260,9 @@
     return loadClass(name, false);
   }
 
+  private native Class loadClassFromSig(String name)
+    throws ClassNotFoundException;
+
   /**
    * Load a class using this ClassLoader or its parent, possibly resolving
    * it as well using <code>resolveClass()</code>. It first tries to find
@@ -324,29 +286,36 @@
   protected synchronized Class loadClass(String name, boolean resolve)
     throws ClassNotFoundException
   {
-    // Have we already loaded this class?
-    Class c = findLoadedClass(name);
-    if (c == null)
+    // Arrays are handled specially.
+    Class c;
+    if (name.charAt(0) == '[')
+      c = loadClassFromSig(name);
+    else
       {
-	// Can the class be loaded by a parent?
-	try
+	// Have we already loaded this class?
+	c = findLoadedClass(name);
+	if (c == null)
 	  {
-	    if (parent == null)
+	    // Can the class be loaded by a parent?
+	    try
 	      {
-		c = VMClassLoader.loadClass(name, resolve);
-		if (c != null)
-		  return c;
+		if (parent == null)
+		  {
+		    c = VMClassLoader.loadClass(name, resolve);
+		    if (c != null)
+		      return c;
+		  }
+		else
+		  {
+		    return parent.loadClass(name, resolve);
+		  }
 	      }
-	    else
+	    catch (ClassNotFoundException e)
 	      {
-		return parent.loadClass(name, resolve);
 	      }
+	    // Still not found, we have to do it ourself.
+	    c = findClass(name);
 	  }
-	catch (ClassNotFoundException e)
-	  {
-	  }
-	// Still not found, we have to do it ourself.
-	c = findClass(name);
       }
     if (resolve)
       resolveClass(c);
@@ -473,7 +442,7 @@
     throws ClassFormatError
   {
     if (domain == null)
-      domain = StaticData.defaultProtectionDomain;
+      domain = defaultProtectionDomain;
     if (! initialized)
       throw new SecurityException("attempt to define class from uninitialized class loader");
     
@@ -508,7 +477,7 @@
   protected final Class findSystemClass(String name)
     throws ClassNotFoundException
   {
-    return Class.forName(name, false, StaticData.systemClassLoader);
+    return Class.forName(name, false, systemClassLoader);
   }
 
   /**
@@ -524,10 +493,11 @@
   public final ClassLoader getParent()
   {
     // Check if we may return the parent classloader.
-    SecurityManager sm = SecurityManager.current;
+    SecurityManager sm = System.getSecurityManager();
     if (sm != null)
       {
-	ClassLoader cl = VMStackWalker.getCallingClassLoader();
+        Class c = VMSecurityManager.getClassContext(ClassLoader.class)[1];
+        ClassLoader cl = c.getClassLoader();
 	if (cl != null && ! cl.isAncestorOf(this))
           sm.checkPermission(new RuntimePermission("getClassLoader"));
       }
@@ -669,7 +639,7 @@
    */
   public static final URL getSystemResource(String name)
   {
-    return StaticData.systemClassLoader.getResource(name);
+    return systemClassLoader.getResource(name);
   }
 
   /**
@@ -685,7 +655,7 @@
    */
   public static Enumeration getSystemResources(String name) throws IOException
   {
-    return StaticData.systemClassLoader.getResources(name);
+    return systemClassLoader.getResources(name);
   }
 
   /**
@@ -740,18 +710,18 @@
 
   /**
    * Returns the system classloader. The system classloader (also called
-   * the application classloader) is the classloader that is used to
+   * the application classloader) is the classloader that was used to
    * load the application classes on the classpath (given by the system
    * property <code>java.class.path</code>. This is set as the context
    * class loader for a thread. The system property
    * <code>java.system.class.loader</code>, if defined, is taken to be the
    * name of the class to use as the system class loader, which must have
-   * a public constructor which takes a ClassLoader as a parent. The parent
-   * class loader passed in the constructor is the default system class
-   * loader.
+   * a public constructor which takes a ClassLoader as a parent; otherwise this
+   * uses gnu.java.lang.SystemClassLoader.
    *
    * <p>Note that this is different from the bootstrap classloader that
-   * actually loads all the real "system" classes.
+   * actually loads all the real "system" classes (the bootstrap classloader
+   * is the parent of the returned system classloader).
    *
    * <p>A security check will be performed for
    * <code>RuntimePermission("getClassLoader")</code> if the calling class
@@ -766,15 +736,16 @@
   public static ClassLoader getSystemClassLoader()
   {
     // Check if we may return the system classloader
-    SecurityManager sm = SecurityManager.current;
+    SecurityManager sm = System.getSecurityManager();
     if (sm != null)
       {
-	ClassLoader cl = VMStackWalker.getCallingClassLoader();
-	if (cl != null && cl != StaticData.systemClassLoader)
+	Class c = VMSecurityManager.getClassContext(ClassLoader.class)[1];
+	ClassLoader cl = c.getClassLoader();
+	if (cl != null && cl != systemClassLoader)
 	  sm.checkPermission(new RuntimePermission("getClassLoader"));
       }
 
-    return StaticData.systemClassLoader;
+    return systemClassLoader;
   }
 
   /**
@@ -933,7 +904,7 @@
   {
     if (packageAssertionStatus == null)
       packageAssertionStatus
-        = new HashMap(StaticData.systemPackageAssertionStatus);
+        = new HashMap(systemPackageAssertionStatus);
     packageAssertionStatus.put(name, Boolean.valueOf(enabled));
   }
   
@@ -953,8 +924,7 @@
                                                    boolean enabled)
   {
     if (classAssertionStatus == null)
-      classAssertionStatus = 
-        new HashMap(StaticData.systemClassAssertionStatus);
+      classAssertionStatus = new HashMap(systemClassAssertionStatus);
     // The toString() hack catches null, as required.
     classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled));
   }
@@ -991,126 +961,4 @@
       }
     return false;
   }
-
-  private static URL[] getExtClassLoaderUrls()
-  {
-    String classpath = SystemProperties.getProperty("java.ext.dirs", "");
-    StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator);
-    ArrayList list = new ArrayList();
-    while (tok.hasMoreTokens())
-      {
-	try
-	  {
-	    File f = new File(tok.nextToken());
-	    File[] files = f.listFiles();
-	    if (files != null)
-	      for (int i = 0; i < files.length; i++)
-		list.add(files[i].toURL());
-	  }
-	catch(Exception x)
-	  {
-	  }
-      }
-    URL[] urls = new URL[list.size()];
-    list.toArray(urls);
-    return urls;
-  }
-
-  private static void addFileURL(ArrayList list, String file)
-  {
-    try
-      {
-	list.add(new File(file).toURL());
-      }
-    catch(java.net.MalformedURLException x)
-      {
-      }
-  }
-
-  private static URL[] getSystemClassLoaderUrls()
-  {
-    String classpath = SystemProperties.getProperty("java.class.path", ".");
-    StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator, true);
-    ArrayList list = new ArrayList();
-    while (tok.hasMoreTokens())
-      {
-	String s = tok.nextToken();
-	if (s.equals(File.pathSeparator))
-	    addFileURL(list, ".");
-	else
-	  {
-	    addFileURL(list, s);
-	    if (tok.hasMoreTokens())
-	      {
-		// Skip the separator.
-		tok.nextToken();
-		// If the classpath ended with a separator,
-		// append the current directory.
-		if (!tok.hasMoreTokens())
-		    addFileURL(list, ".");
-	      }
-	  }
-      }
-    URL[] urls = new URL[list.size()];
-    list.toArray(urls);
-    return urls;
-  }
-
-  static ClassLoader defaultGetSystemClassLoader()
-  {
-    return createAuxiliarySystemClassLoader(
-        createSystemClassLoader(getSystemClassLoaderUrls(),
-            createExtClassLoader(getExtClassLoaderUrls(), null)));
-  }
-
-  static ClassLoader createExtClassLoader(URL[] urls, ClassLoader parent)
-  {
-    if (urls.length > 0)
-      return new URLClassLoader(urls, parent);
-    else
-      return parent;
-  }
-
-  static ClassLoader createSystemClassLoader(URL[] urls, ClassLoader parent)
-  {
-    return
-	new URLClassLoader(urls, parent)
-	{
-	    protected synchronized Class loadClass(String name,
-		boolean resolve)
-		throws ClassNotFoundException
-	    {
-		SecurityManager sm = SecurityManager.current;
-		if (sm != null)
-		{
-		    int lastDot = name.lastIndexOf('.');
-		    if (lastDot != -1)
-			sm.checkPackageAccess(name.substring(0, lastDot));
-		}
-		return super.loadClass(name, resolve);
-	    }
-	};
-  }
-
-  static ClassLoader createAuxiliarySystemClassLoader(ClassLoader parent)
-  {
-    String loader = SystemProperties.getProperty("java.system.class.loader", null);
-    if (loader == null)
-      {
-	return parent;
-      }
-    try
-      {
-	Constructor c = Class.forName(loader, false, parent)
-	    .getConstructor(new Class[] { ClassLoader.class });
-	return (ClassLoader)c.newInstance(new Object[] { parent });
-      }
-    catch (Exception e)
-      {
-	System.err.println("Requested system classloader " + loader + " failed.");
-	throw (Error)
-	    new Error("Requested system classloader " + loader + " failed.")
-		.initCause(e);
-      }
-  }
 }
