/[classpath]/classpath/java/lang/ClassLoader.java
ViewVC logotype

Diff of /classpath/java/lang/ClassLoader.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.13 by mark, Fri Feb 15 15:15:25 2002 UTC revision 1.14 by ericb, Fri Feb 22 20:07:40 2002 UTC
# Line 1  Line 1 
1  /* java.lang.ClassLoader  /* ClassLoader.java -- responsible for loading classes into the VM
2     Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.     Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 7  GNU Classpath is free software; you can Line 7  GNU Classpath is free software; you can
7  it under the terms of the GNU General Public License as published by  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)  the Free Software Foundation; either version 2, or (at your option)
9  any later version.  any later version.
10    
11  GNU Classpath is distributed in the hope that it will be useful, but  GNU Classpath is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Line 48  import gnu.java.util.DoubleEnumeration; Line 48  import gnu.java.util.DoubleEnumeration;
48  import gnu.java.util.EmptyEnumeration;  import gnu.java.util.EmptyEnumeration;
49    
50  /**  /**
51   ** The ClassLoader is a way of customizing the way Java   * The ClassLoader is a way of customizing the way Java gets its classes
52   ** gets its classes and loads them into memory.  The   * and loads them into memory.  The verifier and other standard Java things
53   ** verifier and other standard Java things still run, but   * still run, but the ClassLoader is allowed great flexibility in determining
54   ** the ClassLoader is allowed great flexibility in   * where to get the classfiles and when to load and resolve them. For that
55   ** determining where to get the classfiles and when to   * matter, a custom ClassLoader can perform on-the-fly code generation or
56   ** load and resolve them.   * modification!
57   **   *
58   ** XXX - Not all support has been written for the new 1.2 methods yet!   * XXX - Not all support has been written for the new 1.2 methods yet!
59   **   *
60   ** <p>   * <p>Every classloader has a parent classloader that is consulted before
61   ** Every classloader has a parent classloader that is consulted before   * the 'child' classloader when classes or resources should be loaded.
62   ** the 'child' classloader when classes or resources should be loaded.   * This is done to make sure that classes can be loaded from an hierarchy of
63   ** This is done to make sure that classes can be loaded from an hierarchy of   * multiple classloaders and classloaders do not accidentially redefine
64   ** multiple classloaders and classloaders do not accidentially redefine   * already loaded classes by classloaders higher in the hierarchy.
65   ** already loaded classes by classloaders higher in the hierarchy.   *
66   ** <p>   * <p>The grandparent of all classloaders is the bootstrap classloader, which
67   ** The grandparent of all classloaders is the bootstrap classloader.   * loads all the standard system classes as implemented by GNU Classpath. The
68   ** It is one of two special classloaders.   * other special classloader is the system classloader (also called
69   ** The bootstrap classloader loads all the standard system classes as   * application classloader) that loads all classes from the CLASSPATH
70   ** implemented by GNU Classpath. The other special classloader is the   * (<code>java.class.path</code> system property). The system classloader
71   ** system classloader (also called application classloader) that loads   * is responsible for finding the application classes from the classpath,
72   ** all classes from the classpath (<code>java.class.path</code> system   * and delegates all requests for the standard library classes to its parent
73   ** property). The system classloader is responsible for finding the   * the bootstrap classloader. Most programs will load all their classes
74   ** application classes from the classpath, and delegates all requests for   * through the system classloaders.
75   ** the standard library classes to its parent the bootstrap classloader.   *
76   ** Most programs will load all their classes through the system classloaders.   * <p>The bootstrap classloader in GNU Classpath is implemented as a couple of
77   ** <p>   * static (native) methods on the package private class
78   ** The bootstrap classloader in GNU Classpath is implemented as a couple of   * <code>java.lang.VMClassLoader</code>, the system classloader is an
79   ** static (native) methods on the package private class   * instance of <code>gnu.java.lang.SystemClassloader</code>
80   ** <code>java.lang.VMClassLoader</code>, the system classloader is an   * (which is a subclass of <code>java.net.URLClassLoader</code>).
81   ** instance of <code>gnu.java.lang.SystemClassloader</code>   *
82   ** (which is a subclass of <code>java.net.URLClassLoader</code>).   * <p>Users of a <code>ClassLoader</code> will normally just use the methods
83   ** <p>   * <ul>
84   ** Users of a <code>ClassLoader</code> will normally just use the methods   *  <li> <code>loadClass()</code> to load a class.</li>
85   ** <ul>   *  <li> <code>getResource()</code> or <code>getResourceAsStream()</code>
86   ** <li> <code>loadClass()</code> to load a class.   *       to access a resource.</li>
87   ** <li> <code>getResource()</code> or <code>getResourceAsStream()</code>   *  <li> <code>getResources()</code> to get an Enumeration of URLs to all
88   ** to access a resource.   *       the resources provided by the classloader and its parents with the
89   ** <li> <code>getResources()</code> to get an Enumeration of URLs to all   *       same name.</li>
90   ** the resources provided by the classloader and its parents with the same   * </ul>
91   ** name.   *
92   ** </ul>   * <p>Subclasses should implement the methods
93   ** <p>   * <ul>
94   ** Subclasses should implement the methods   *  <li> <code>findClass()</code> which is called by <code>loadClass()</code>
95   ** <ul>   *       when the parent classloader cannot provide a named class.</li>
96   ** <li> <code>findClass()</code> which is called by <code>loadClass()</code>   *  <li> <code>findResource()</code> which is called by
97   ** when the parent classloader cannot provide a named class.   *       <code>getResource()</code> when the parent classloader cannot provide
98   ** <li> <code>findResource()</code> which is called by   *       a named resource.</li>
99   ** <code>getResource()</code> when the parent classloader cannot provide   *  <li> <code>findResources()</code> which is called by
100   ** a named resource.   *       <code>getResource()</code> to combine all the resources with the
101   ** <li> <code>findResources()</code> which is called by   *       same name from the classloader and its parents.</li>
102   ** <code>getResource()</code> to combine all the resources with the same name   *  <li> <code>findLibrary()</code> which is called by
103   ** from the classloader and its parents.   *       <code>Runtime.loadLibrary()</code> when a class defined by the
104   ** <li> <code>findLibrary()</code> which is called by   *       classloader wants to load a native library.</li>
105   ** <code>Runtime.loadLibrary()</code> when a class defined by the classloader   * </ul>
106   ** wants to load a native library.   *
107   ** </ul>   * @author John Keiser
108   **   * @author Mark Wielaard
109   ** @author John Keiser   * @author Eric Blake <ebb9@email.byu.edu>
110   ** @author Mark Wielaard   * @see Class
111   ** @version 1.1.99, Jan 2000   * @since 1.0
112   ** @since JDK1.0   * @status still missing 1.4 functionality
113   **/   */
114    public abstract class ClassLoader
115  public abstract class ClassLoader {  {
116          /* Each instance gets a list of these. */    /** All classes loaded by this classloader. */
117          private Hashtable loadedClasses = new Hashtable();    private Hashtable loadedClasses = new Hashtable();
118    
119      /* Each instance gets a list of these. */    /** All packages defined by this classloader. */
120      private Hashtable definedPackages = new Hashtable();    private Hashtable definedPackages = new Hashtable();
121    
122      /* The classloader that is consulted before this classloader.    /**
123         if null then the parent is the bootstrap classloader. */     * The classloader that is consulted before this classloader.
124      private final ClassLoader parent;     * If null then the parent is the bootstrap classloader.
125       */
126      /* System/Application classloader gnu.java.lang.SystemClassLoader. */    private final ClassLoader parent;
127      static final ClassLoader systemClassLoader  
128          = null; // XXX = SystemClassLoader.getInstance();    /**
129       * System/Application classloader gnu.java.lang.SystemClassLoader.
130      /** Create a new ClassLoader with as parent the system classloader.     * Due to bootstrapping issues, the VM must modify this field.
131       ** @exception SecurityException if you do not have permission     */
132       **            to create a ClassLoader.    static final ClassLoader systemClassLoader
133       **/      = null; // XXX = SystemClassLoader.getInstance();
134      protected ClassLoader() throws SecurityException {  
135          this(systemClassLoader);    /**
136      }     * The desired assertion status of classes loaded by this loader, if not
137       * overridden by package or class instructions.
138      /** Create a new ClassLoader with the specified parent.     * @XXX Implement for 1.4 compatibility.
139       ** The parent will be consulted when a class or resource is    // Package visible for use by Class.
140       ** requested through <code>loadClass()</code> or    boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus();
141       ** <code>getResource()</code>. Only when the parent classloader     */
142       ** cannot provide the requested class or resource the  
143       ** <code>findClass()</code> or <code>findResource()</code> method    /**
144       ** of this classloader will be called.     * The command-line state of the package assertion status overrides. This
145       **     * map is never modified, so it does not need to be synchronized.
146       ** @param parent the classloader that should be consulted before     * @XXX Implement for 1.4 compatibility.
147       ** this classloader. Use <code>null</code> to specify the bootstrap    // Package visible for use by Class.
148       ** classloader.    static final Map systemPackageAssertionStatus
149       ** @exception SecurityException if you do not have permission      = VMClassLoader.packageAssertionStatus();
150       **            to create a ClassLoader.     */
151       **  
152       ** @since 1.2    /**
153       **/     * The map of package assertion status overrides, or null if no package
154      protected ClassLoader(ClassLoader parent) {     * overrides have been specified yet. The values of the map should be
155          // May we create a new classloader?     * Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented
156          SecurityManager sm = System.getSecurityManager();     * by the null key. This map must be synchronized on this instance.
157          if (sm != null)     * @XXX Implement for 1.4 compatibility.
158              sm.checkCreateClassLoader();    // Package visible for use by Class.
159              Map packageAssertionStatus;
160          this.parent = parent;     */
161      }  
162          /**
163          /** Load a class using this ClassLoader or its parent,     * The command-line state of the class assertion status overrides. This
164           ** without resolving it. Calls <code>loadClass(name, false)</code>.     * map is never modified, so it does not need to be synchronized.
165           ** <p>     * @XXX Implement for 1.4 compatibility.
166           ** Subclasses should not override this method but should override    // Package visible for use by Class.
167           ** <code>findClass()</code> which is called by this method.    static final Map systemClassAssertionStatus
168           **      = VMClassLoader.classAssertionStatus();
169           ** @param name the name of the class relative to this ClassLoader.     */
170           ** @exception ClassNotFoundException if the class cannot be found to  
171           **            be loaded.    /**
172           ** @return the loaded class.     * The map of class assertion status overrides, or null if no class
173           **/     * overrides have been specified yet. The values of the map should be
174          public Class loadClass(String name) throws ClassNotFoundException {     * Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this
175                  return loadClass(name,false);     * instance.
176          }     * @XXX Implement for 1.4 compatibility.
177      // Package visible for use by Class.
178          /** Load a class using this ClassLoader or its parent,    Map classAssertionStatus;
179           ** possibly resolving it as well using <code>resolveClass()</code>.     */
180           ** It first tries to find out if the class has already been loaded  
181           ** through this classloader by calling <code>findLoadedClass()</code>.    /**
182           ** Then it calls <code>loadClass()</code> on the parent classloader     * Create a new ClassLoader with as parent the system classloader. There
183           ** (or when there is no parent on the bootstrap classloader).     * may be a security check for <code>checkCreateClassLoader</code>.
184           ** When the parent could not load the class it tries to create     *
185           ** a new class by calling <code>findClass()</code>. Finally when     * @throws SecurityException if the security check fails
186           ** <code>resolve</code> is <code>true</code> it also calls     */
187           ** <code>resolveClass()</code> on the newly loaded class.    protected ClassLoader() throws SecurityException
188           ** <p>    {
189           ** Subclasses should not override this method but should override      //XXX This should be this(getSystemClassLoader());
190           ** <code>findClass()</code> which is called by this method.      this(systemClassLoader);
191           **    }
192           ** @param name the fully qualified name of the class to load.  
193           ** @param resolve whether or not to resolve the class.    /**
194           ** @exception ClassNotFoundException if the class cannot be found to     * Create a new ClassLoader with the specified parent. The parent will
195           **            be loaded.     * be consulted when a class or resource is requested through
196           ** @return the loaded class.     * <code>loadClass()</code> or <code>getResource()</code>. Only when the
197           **/     * parent classloader cannot provide the requested class or resource the
198       * <code>findClass()</code> or <code>findResource()</code> method
199       * of this classloader will be called. There may be a security check for
200       * <code>checkCreateClassLoader</code>.
201       *
202       * @param parent the classloader's parent, or null for the bootstrap
203       *        classloader
204       * @throws SecurityException if the security check fails
205       * @since 1.2
206       */
207      protected ClassLoader(ClassLoader parent)
208      {
209        // May we create a new classloader?
210        SecurityManager sm = System.getSecurityManager();
211        if (sm != null)
212          sm.checkCreateClassLoader();
213        this.parent = parent;
214      }
215    
216      /**
217       * Load a class using this ClassLoader or its parent, without resolving
218       * it. Calls <code>loadClass(name, false)</code>.
219       *
220       * <p>Subclasses should not override this method but should override
221       * <code>findClass()</code> which is called by this method.
222       *
223       * @param name the name of the class relative to this ClassLoader
224       * @return the loaded class
225       * @throws ClassNotFoundException if the class cannot be found
226       */
227      public Class loadClass(String name) throws ClassNotFoundException
228      {
229        return loadClass(name, false);
230      }
231    
232      /**
233       * Load a class using this ClassLoader or its parent, possibly resolving
234       * it as well using <code>resolveClass()</code>. It first tries to find
235       * out if the class has already been loaded through this classloader by
236       * calling <code>findLoadedClass()</code>. Then it calls
237       * <code>loadClass()</code> on the parent classloader (or when there is
238       * no parent on the bootstrap classloader). When the parent could not load
239       * the class it tries to create a new class by calling
240       * <code>findClass()</code>. Finally when <code>resolve</code> is
241       * <code>true</code> it also calls <code>resolveClass()</code> on the
242       * newly loaded class.
243       *
244       * <p>Subclasses should not override this method but should override
245       * <code>findClass()</code> which is called by this method.
246       *
247       * @param name the fully qualified name of the class to load
248       * @param resolve whether or not to resolve the class
249       * @return the loaded class
250       * @throws ClassNotFoundException if the class cannot be found
251       */
252      protected synchronized Class loadClass(String name, boolean resolve)      protected synchronized Class loadClass(String name, boolean resolve)
253          throws ClassNotFoundException        throws ClassNotFoundException
254      {      {
255          // Have we already loaded this class?        // Have we already loaded this class?
256          Class c = findLoadedClass(name);        Class c = findLoadedClass(name);
257          if (c != null)        if (c != null)
             return c;  
           
         // Can the class be loaded by one of our parent?  
         try {  
             if (parent == null)  
                 // XXX - use the bootstrap classloader  
                 // return VMClassLoader.loadClass(name, resolve);  
                 return findSystemClass(name);  
             else  
                 return parent.loadClass(name, resolve);  
         } catch (ClassNotFoundException e) { /* ignore use findClass() */ }  
           
         // Still not found, we have to do it ourselfs.  
         c = findClass(name);  
           
         // resolve if necessary  
         if (resolve)  
             resolveClass(c);  
           
258          return c;          return c;
     }  
       
     /** Get the URL to a resource using this classloader  
      ** or one of its parents. First tries to get the resource by calling  
      ** <code>getResource()</code> on the parent classloader.  
      ** If the parent classloader returns null then it tries finding the  
      ** resource by calling <code>findResource()</code> on this  
      ** classloader.  
      ** <p>  
      ** Subclasses should not override this method but should override  
      ** <code>findResource()</code> which is called by this method.  
      **  
      ** @param name the name of the resource relative to this  
      **        classloader.  
      ** @return the URL to the resource or null when not found.  
      **/  
     public URL getResource(String name) {  
         URL result;  
           
         if (parent == null)  
             // XXX - try bootstrap classloader;  
             // result = VMClassLoader.getResource(name);  
             return ClassLoader.getSystemResource(name);  
         else  
             result = parent.getResource(name);  
           
         if (result == null)  
             result = findResource(name);  
           
         return result;  
         }  
   
     /** Get a resource as stream using this classloader or one of its  
      ** parents. First calls <code>getResource()</code> and if that  
      ** returns a URL to the resource then it calls and returns the  
      ** InputStream given by <code>URL.openStream()</code>.  
      ** <p>  
      ** Subclasses should not override this method but should override  
      ** <code>findResource()</code> which is called by this method.  
      **  
      ** @param name the name of the resource relative to this  
      **        classloader.  
      ** @return An InputStream to the resource or null when the resource  
      ** could not be found or when the stream could not be opened.  
      **/  
     public InputStream getResourceAsStream(String name) {  
         URL url = getResource(name);  
         if (url == null)  
             return(null);  
           
         try {  
             return url.openStream();  
         } catch(IOException e) {  
             return null;  
         }  
     }  
       
         /** Helper to define a class using a string of bytes.  
          ** @param data the data representing the classfile, in classfile format.  
          ** @param offset the offset into the data where the classfile starts.  
          ** @param len the length of the classfile data in the array.  
          ** @return the class that was defined.  
          ** @deprecated use defineClass(String,...) instead.  
          **/  
         protected final Class defineClass(byte[] data, int offset, int len) throws ClassFormatError {  
                 return defineClass(null,data,offset,len);  
         }  
   
         /** Helper to define a class using a string of bytes without a  
          ** ProtectionDomain.  
          ** <p>  
          ** Subclasses should call this method from their  
          ** <code>findClass()</code> implementation.  
          ** @param name the name to give the class.  null if unknown.  
          ** @param data the data representing the classfile, in classfile format.  
          ** @param offset the offset into the data where the classfile starts.  
          ** @param len the length of the classfile data in the array.  
          ** @return the class that was defined.  
          ** @exception ClassFormatError if the byte array is not in proper classfile format.  
          **/  
         protected final Class defineClass(String name, byte[] data, int offset, int len) throws ClassFormatError {  
         // XXX - return defineClass(name,data,offset,len,null);  
                 Class retval = VMClassLoader.defineClass(this,name,data,offset,len);  
                 loadedClasses.put(retval.getName(),retval);  
                 return retval;  
         }  
   
     /** Helper to define a class using a string of bytes.  
      ** <p>  
      ** Subclasses should call this method from their  
      ** <code>findClass()</code> implementation.  
      **  
      ** XXX - not implemented yet. Needs native support.  
      **  
      ** @param name the name to give the class.  null if unknown.  
      ** @param data the data representing the classfile, in classfile format.  
      ** @param offset the offset into the data where the classfile starts.  
      ** @param len the length of the classfile data in the array.  
      ** @param domain the ProtectionDomain to give to the class.  
      ** null if unknown (the class will get the default protection domain).  
      ** @return the class that was defined.  
      ** @exception ClassFormatError if the byte array is not in proper  
      ** classfile format.  
      **  
      ** @since 1.2  
      **/  
     protected final Class defineClass(String name, byte[] data, int offset,  
                                       int len, ProtectionDomain domain)  
         throws ClassFormatError  
     {  
         /*  
           XXX - needs native support.  
           Class retval  
           = VMClassLoader.defineClass(this,name,data,offset,len,domain);  
             loadedClasses.put(retval.getName(),retval);  
           return retval;  
         */  
         return defineClass(name, data, offset, len);  
     }  
   
         /** Helper to resolve all references to other classes from this class.  
          ** @param c the class to resolve.  
          **/  
         protected final void resolveClass(Class c) {  
                 VMClassLoader.resolveClass(c);  
         }  
   
         /** Helper to find a Class using the system classloader,  
          ** possibly loading it.  
          ** @param name the name of the class to find.  
          ** @return the found class  
          ** @exception ClassNotFoundException if the class cannot be found.  
          **/  
         protected final Class findSystemClass(String name) throws ClassNotFoundException {  
                 return Class.forName(name);  
         }  
   
         /** Helper to set the signers of a class.  
          ** @param c the Class to set signers of  
          ** @param signers the signers to set  
          **/  
         protected final void setSigners(Class c, Object[] signers) {  
                 c.setSigners(signers);  
         }  
   
         /** Helper to find an already-loaded class in this ClassLoader.  
          ** @param name the name of the class to find.  
          ** @return the found Class, or null if it is not found.  
          **/  
         protected final Class findLoadedClass(String name) {  
                 return (Class)loadedClasses.get(name);  
         }  
   
         /** Get the URL to a resource using the system classloader.  
          ** @param name the name of the resource relative to the  
          **        system classloader.  
          ** @return the URL to the resource.  
          **/  
         public static final URL getSystemResource(String name) {  
                 if (name.startsWith("/"))  
                         name = name.substring(1);  
                 String cp = System.getProperty("java.class.path");  
                 if (cp == null)  
                         return(null);  
   
                 StringTokenizer st = new StringTokenizer(cp,  
                                                          File.pathSeparator);  
                 while(st.hasMoreTokens()) {  
                         String path = st.nextToken();  
                         if (path.toLowerCase().endsWith(".zip") ||  
                             path.toLowerCase().endsWith(".jar"))  
                                 return(null); // Not implemented yet  
                         File f;  
                         if (path.endsWith(File.separator))  
                                 f = new File(path + name);  
                         else  
                                 f = new File(path + File.separator + name);  
   
                         if (f.exists())  
                                 try {  
                                         return new URL("file://" +  
                                                         f.getAbsolutePath());  
                                 } catch(MalformedURLException e) {  
                                         return null;  
                                 }  
                 }  
                 return(null);  
         }  
   
         /** Get a resource using the system classloader.  
          ** @param name the name of the resource relative to the  
          **        system classloader.  
          ** @return the resource.  
          **/  
         public static final InputStream getSystemResourceAsStream(String name) {  
                 try {  
                         URL url = getSystemResource(name);  
                         if (url == null)  
                                 return(null);  
                         return url.openStream();  
                 } catch(IOException e) {  
                         return null;  
                 }  
         }  
   
     /**  
      * Defines a new package and creates a Package object.  
      * The package should be defined before any class in the package is  
      * defined with <code>defineClass()</code>. The package should not yet  
      * be defined before in this classloader or in one of its parents (which  
      * means that <code>getPackage()</code> should return <code>null</code>).  
      * All parameters except the <code>name</code> of the package may be  
      * <code>null</code>.  
      * <p>  
      * Subclasses should call this method from their <code>findClass()</code>  
      * implementation before calling <code>defineClass()</code> on a Class  
      * in a not yet defined Package (which can be checked by calling  
      * <code>getPackage()</code>).  
      *  
      * @param name The name of the Package  
      * @param specTitle The name of the specification  
      * @param specVendor The name of the specification designer  
      * @param specVersion The version of this specification  
      * @param implTitle The name of the implementation  
      * @param implVendor The vendor that wrote this implementation  
      * @param implVersion The version of this implementation  
      * @param sealed If sealed the origin of the package classes  
      * @return the Package object for the specified package  
      *  
      * @exception IllegalArgumentException if the package name is null or if  
      * it was already defined by this classloader or one of its parents.  
      *  
      * @see Package  
      * @since 1.2  
      */  
     protected Package definePackage(String name,  
             String specTitle, String specVendor, String specVersion,  
             String implTitle, String implVendor, String implVersion,  
             URL sealed) {  
   
         if (getPackage(name) != null)  
             throw new IllegalArgumentException("Package " + name  
                                                + " already defined");  
         Package p = new Package(name,  
                                 specTitle, specVendor, specVersion,  
                                 implTitle, implVendor, implVersion,  
                                 sealed);  
         definedPackages.put(name, p);  
   
         return p;  
     }  
   
     /**  
      * Returns the Package object for the requested package name. It returns  
      * null when the package is not defined by this classloader or one of its  
      * parents.  
      *  
      * @since 1.2  
      */  
     protected final Package getPackage(String name) {  
         Package p;  
         if (parent == null)  
             // XXX - Should we use the bootstrap classloader?  
             p = null;  
         else  
             p = parent.getPackage(name);  
   
         if (p == null)  
             p = (Package)definedPackages.get(name);  
   
         return p;  
     }  
   
     /**  
      * Returns all Package objects defined by this classloader and its parents.  
      *  
      * @since 1.2  
      */  
     protected Package[] getPackages() {  
         Package[] allPackages;  
           
         // Get all our packages.  
         Package[] packages;  
         synchronized(definedPackages) {  
             packages = new Package[definedPackages.size()];  
             Enumeration e = definedPackages.elements();  
             int i = 0;  
             while (e.hasMoreElements()) {  
                 packages[i] = (Package)e.nextElement();  
                 i++;  
             }  
         }  
           
         // If we have a parent get all packages defined by our parents.  
         if (parent != null) {  
             Package[] parentPackages = parent.getPackages();  
             allPackages = new Package[parentPackages.length+packages.length];  
             System.arraycopy(parentPackages, 0, allPackages, 0,  
                              parentPackages.length);  
             System.arraycopy(packages, 0, allPackages, parentPackages.length,  
                              packages.length);  
         } else  
             // XXX - Should we use the bootstrap classloader?  
             allPackages = packages;  
           
         return allPackages;  
     }  
259    
260      /**        // Can the class be loaded by one of our parent?
261       * Returns the parent of this classloader.        try
262       * If the parent of this classloader is the bootstrap classloader then          {
263       * this method returns <code>null</code>.            if (parent == null)
264       *              // XXX - use the bootstrap classloader
265       * @exception SecurityException thrown when the classloader of the calling              // return VMClassLoader.loadClass(name, resolve);
266       * class is not the bootstrap (null) or the current classloader and the              return findSystemClass(name);
267       * caller also doesn't have the            return parent.loadClass(name, resolve);
      * <code>RuntimePermission("getClassLoader")</code>.  
      *  
      * @since 1.2  
      */  
     public final ClassLoader getParent() {  
         // Check if we may return the parent classloader  
         SecurityManager sm = System.getSecurityManager();  
         if (sm != null) {  
             Class c = VMSecurityManager.getClassContext()[1];  
             ClassLoader cl = c.getClassLoader();  
             if (cl != null && cl != this)  
                 sm.checkPermission(new RuntimePermission("getClassLoader"));  
268          }          }
269          return parent;        catch (ClassNotFoundException e)
270      }          {
271              // Ignore, use findClass().
     /**  
      * Returns the system classloader. The system classloader (also called  
      * 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>.  
      * <p>  
      * Note that this is different from the bootstrap classloader that  
      * actually loads all the real "system" classes (the bootstrap classloader  
      * is the parent of the returned system classloader).  
      *  
      * @exception SecurityException thrown when the classloader of the calling  
      * class is not the bootstrap (null) or system classloader and the caller  
      * also doesn't have the <code>RuntimePermission("getClassLoader")</code>.  
      *  
      * @since 1.2  
      */  
     public static ClassLoader getSystemClassLoader() {  
         // Check if we may return the system classloader  
         SecurityManager sm = System.getSecurityManager();  
         if (sm != null) {  
             Class c = VMSecurityManager.getClassContext()[1];  
             ClassLoader cl = c.getClassLoader();  
             if (cl != null && cl != systemClassLoader)  
                 sm.checkPermission(new RuntimePermission("getClassLoader"));  
272          }          }
         return systemClassLoader;  
     }  
   
     /**  
      * Called for every class name that is needed but has not yet been  
      * defined by this classloader or one of its parents. It is called by  
      * <code>loadClass()</code> after both <code>findLoadedClass()</code> and  
      * <code>parent.loadClass()</code> couldn't provide the requested class.  
      * <p>  
      * The default implementation throws a <code>ClassNotFoundException</code>.  
      * Subclasses should override this method. An implementation of this  
      * method in a subclass should get the class bytes of the class (if it can  
      * find them), if the package of the requested class doesn't exist it  
      * should define the package and finally it should call define the actual  
      * class. It does not have to resolve the class. It should look something  
      * like the following:  
      * <p>  
      <pre>  
          // Get the bytes that describe the requested class  
          byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name);  
          // Get the package name  
          int lastDot = name.lastIndexOf('.');  
          if (lastDot != -1) {  
              String packageName = name.substring(0,lastDot);  
              // Look if the package already exists  
              if (getPackage(pkg) == null) {  
                  // define the package  
                  definePackage(packageName, ...);  
              }  
          // Define and return the class  
          return defineClass(name, classBytes, 0, classBytes.length);  
      </pre>  
      * <p>  
      * <code>loadClass()</code> makes sure that the <code>Class</code>  
      * returned by <code>findClass()</code> will later be returned by  
      * <code>findLoadedClass()</code> when the same class name is  
      * requested.  
      *  
      * @param name class name to find (including the package name)  
      * @return the requested Class  
      * @exception ClassNotFoundException when the class can not be found  
      *  
      * @since 1.2  
      */  
     protected Class findClass(String name) throws ClassNotFoundException {  
         throw new ClassNotFoundException(name);  
     }  
   
     /**  
      * Called whenever a resource is needed that could not be provided by  
      * one of the parents of this classloader. It is called by  
      * <code>getResource()</code> after <code>parent.getResource()</code>  
      * couldn't provide the requested resource.  
      * <p>  
      * The default implementation always returns null. Subclasses should  
      * override this method when they can provide a way to return a URL  
      * to a named resource.  
      *  
      * @param name the name of the resource to be found.  
      * @return a URL to the named resource or null when not found.  
      *  
      * @since 1.2  
      */  
     protected URL findResource(String name) {  
         return null;  
     }  
   
     /**  
      * Called whenever all locations of a named resource are needed.  
      * It is called by <code>getResources()</code> after it has called  
      * <code>parent.getResources()</code>. The results are combined by  
      * the <code>getResources()</code> method.  
      * <p>  
      * The default implementation always returns an empty Enumeration.  
      * Subclasses should override it when they can provide an Enumeration of  
      * URLS (possibly just one element) to the named resource.  
      * The first URL of the Enumeration should be the same as the one  
      * returned by <code>findResource</code>.  
      *  
      * @param name the name of the resource to be found.  
      * @return a possibly empty Enumeration of URLs to the named resource.  
      *  
      * @since 1.2  
      */  
     protected Enumeration findResources(String name) throws IOException {  
         return EmptyEnumeration.getInstance();  
     }  
273    
274      /**        // Still not found, we have to do it ourself.
275       * Returns an Enumeration of all resources with a given name that can        c = findClass(name);
276       * be found by this classloader and its parents. Certain classloaders        if (resolve)
277       * (such as the URLClassLoader when given multiple jar files) can have          resolveClass(c);
278       * multiple resources with the same name that come from multiple locations.        return c;
279       * It can also occur that a parent classloader offers a resource with a      }
280       * certain name and the child classloader also offers a resource with that  
281       * same name. <code>getResource() only offers the first resource (of the    /**
282       * parent) with a given name. This method lists all resources with the     * Called for every class name that is needed but has not yet been
283       * same name.     * defined by this classloader or one of its parents. It is called by
284       * <p>     * <code>loadClass()</code> after both <code>findLoadedClass()</code> and
285       * The Enumeration is created by first calling <code>getResources()</code>     * <code>parent.loadClass()</code> couldn't provide the requested class.
286       * on the parent classloader and then calling <code>findResources()</code>     *
287       * on this classloader.     * <p>The default implementation throws a
288       *     * <code>ClassNotFoundException</code>. Subclasses should override this
289       * @since 1.2     * method. An implementation of this method in a subclass should get the
290       */     * class bytes of the class (if it can find them), if the package of the
291      public final Enumeration getResources(String name) throws IOException {     * requested class doesn't exist it should define the package and finally
292          Enumeration parentResources;     * it should call define the actual class. It does not have to resolve the
293          if (parent == null)     * class. It should look something like the following:<br>
294              // XXX - Should use the bootstrap classloader     *
295              parentResources = EmptyEnumeration.getInstance();     * <pre>
296       * // Get the bytes that describe the requested class
297       * byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name);
298       * // Get the package name
299       * int lastDot = name.lastIndexOf('.');
300       * if (lastDot != -1)
301       *   {
302       *     String packageName = name.substring(0, lastDot);
303       *     // Look if the package already exists
304       *     if (getPackage(pkg) == null)
305       *       {
306       *         // define the package
307       *         definePackage(packageName, ...);
308       *       }
309       *   }
310       * // Define and return the class
311       *  return defineClass(name, classBytes, 0, classBytes.length);
312       * </pre>
313       *
314       * <p><code>loadClass()</code> makes sure that the <code>Class</code>
315       * returned by <code>findClass()</code> will later be returned by
316       * <code>findLoadedClass()</code> when the same class name is requested.
317       *
318       * @param name class name to find (including the package name)
319       * @return the requested Class
320       * @throws ClassNotFoundException when the class can not be found
321       * @since 1.2
322       */
323      protected Class findClass(String name) throws ClassNotFoundException
324      {
325        throw new ClassNotFoundException(name);
326      }
327    
328      /**
329       * Helper to define a class using a string of bytes. This version is not
330       * secure.
331       *
332       * @param data the data representing the classfile, in classfile format
333       * @param offset the offset into the data where the classfile starts
334       * @param len the length of the classfile data in the array
335       * @return the class that was defined
336       * @throws ClassFormatError if data is not in proper classfile format
337       * @throws IndexOutOfBoundsException if offset or len is negative, or
338       *         offset + len exceeds data
339       * @deprecated use {@link #defineClass(String, byte[], int, int)} instead
340       */
341      protected final Class defineClass(byte[] data, int offset, int len)
342        throws ClassFormatError
343      {
344        return defineClass(null, data, offset, len);
345      }
346    
347      /**
348       * Helper to define a class using a string of bytes without a
349       * ProtectionDomain. Subclasses should call this method from their
350       * <code>findClass()</code> implementation. The name should use '.'
351       * separators, and discard the trailing ".class".  The default protection
352       * domain is <code>Policy.getPolicy().getPermissions(null, null)<code>.
353       *
354       * @param name the name to give the class, or null if unknown
355       * @param data the data representing the classfile, in classfile format
356       * @param offset the offset into the data where the classfile starts
357       * @param len the length of the classfile data in the array
358       * @return the class that was defined
359       * @throws ClassFormatError if data is not in proper classfile format
360       * @throws IndexOutOfBoundsException if offset or len is negative, or
361       *         offset + len exceeds data
362       * @throws SecurityException if name starts with "java."
363       * @since 1.1
364       */
365      protected final Class defineClass(String name, byte[] data, int offset,
366                                        int len) throws ClassFormatError
367      {
368        // XXX - return defineClass(name, data, offset, len, null);
369        Class retval = VMClassLoader.defineClass(this, name, data, offset, len);
370        loadedClasses.put(retval.getName(), retval);
371        return retval;
372      }
373    
374      /**
375       * Helper to define a class using a string of bytes. Subclasses should call
376       * this method from their <code>findClass()</code> implementation. If the
377       * domain is null, the default of
378       * <code>Policy.getPolicy().getPermissions(null, null)<code> is used.
379       * Once a class has been defined in a package, all further classes in that
380       * package must have the same set of certificates or a SecurityException is
381       * thrown
382       *
383       * XXX - not implemented yet. Needs native support.
384       *
385       * @param name the name to give the class.  null if unknown
386       * @param data the data representing the classfile, in classfile format
387       * @param offset the offset into the data where the classfile starts
388       * @param len the length of the classfile data in the array
389       * @param domain the ProtectionDomain to give to the class, null for the
390       *        default protection domain
391       * @return the class that was defined
392       * @throws ClassFormatError if data is not in proper classfile format
393       * @throws IndexOutOfBoundsException if offset or len is negative, or
394       *         offset + len exceeds data
395       * @throws SecurityException if name starts with "java.", or if certificates
396       *         do not match up
397       * @since 1.2
398       */
399      protected final Class defineClass(String name, byte[] data, int offset,
400                                        int len, ProtectionDomain domain)
401        throws ClassFormatError
402      {
403        /* XXX - needs native support.
404        Class retval
405          = VMClassLoader.defineClass(this, name, data, offset, len, domain);
406        loadedClasses.put(retval.getName(), retval);
407        return retval;
408        */
409        return defineClass(name, data, offset, len);
410      }
411    
412      /**
413       * Links the class, if that has not already been done. Linking basically
414       * resolves all references to other classes made by this class.
415       *
416       * @param c the class to resolve
417       * @throws NullPointerException if c is null
418       * @throws LinkageError if linking fails
419       */
420      protected final void resolveClass(Class c)
421      {
422        VMClassLoader.resolveClass(c);
423      }
424    
425      /**
426       * Helper to find a Class using the system classloader, possibly loading it.
427       * A subclass usually does not need to call this, if it correctly
428       * overrides <code>findClass(String)</code>.
429       *
430       * @param name the name of the class to find
431       * @return the found class
432       * @throws ClassNotFoundException if the class cannot be found
433       */
434      protected final Class findSystemClass(String name)
435        throws ClassNotFoundException
436      {
437        // XXX This should be:
438        // return Class.forName(name, false, getSystemClassLoader());
439        return Class.forName(name);
440      }
441    
442      /**
443       * Returns the parent of this classloader. If the parent of this
444       * classloader is the bootstrap classloader then this method returns
445       * <code>null</code>. A security check may be performed on
446       * <code>RuntimePermission("getClassLoader")</code>.
447       *
448       * @throws SecurityException if the security check fails
449       * @since 1.2
450       */
451      public final ClassLoader getParent()
452      {
453        // Check if we may return the parent classloader
454        SecurityManager sm = System.getSecurityManager();
455        if (sm != null)
456          {
457            Class c = VMSecurityManager.getClassContext()[1];
458            ClassLoader cl = c.getClassLoader();
459            if (cl != null && cl != this)
460              sm.checkPermission(new RuntimePermission("getClassLoader"));
461          }
462        return parent;
463      }
464    
465      /**
466       * Helper to set the signers of a class. This should be called after
467       * defining the class.
468       *
469       * @param c the Class to set signers of
470       * @param signers the signers to set
471       * @since 1.1
472       */
473      protected final void setSigners(Class c, Object[] signers)
474      {
475        c.setSigners(signers);
476      }
477    
478      /**
479       * Helper to find an already-loaded class in this ClassLoader.
480       *
481       * @param name the name of the class to find
482       * @return the found Class, or null if it is not found
483       * @since 1.1
484       */
485      protected final Class findLoadedClass(String name)
486      {
487        return (Class) loadedClasses.get(name);
488      }
489    
490      /**
491       * Get the URL to a resource using this classloader or one of its parents.
492       * First tries to get the resource by calling <code>getResource()</code>
493       * on the parent classloader. If the parent classloader returns null then
494       * it tries finding the resource by calling <code>findResource()</code> on
495       * this classloader. The resource name should be separated by '/' for path
496       * elements.
497       *
498       * <p>Subclasses should not override this method but should override
499       * <code>findResource()</code> which is called by this method.
500       *
501       * @param name the name of the resource relative to this classloader
502       * @return the URL to the resource or null when not found
503       */
504      public URL getResource(String name)
505      {
506        URL result;
507    
508        if (parent == null)
509          // XXX - try bootstrap classloader;
510          // result = VMClassLoader.getResource(name);
511          return ClassLoader.getSystemResource(name);
512        result = parent.getResource(name);
513    
514        if (result == null)
515          result = findResource(name);
516        return result;
517      }
518    
519      /**
520       * Returns an Enumeration of all resources with a given name that can
521       * be found by this classloader and its parents. Certain classloaders
522       * (such as the URLClassLoader when given multiple jar files) can have
523       * multiple resources with the same name that come from multiple locations.
524       * It can also occur that a parent classloader offers a resource with a
525       * certain name and the child classloader also offers a resource with that
526       * same name. <code>getResource() only offers the first resource (of the
527       * parent) with a given name. This method lists all resources with the
528       * same name. The name should use '/' as path separators.
529       *
530       * <p>The Enumeration is created by first calling <code>getResources()</code>
531       * on the parent classloader and then calling <code>findResources()</code>
532       * on this classloader.
533       *
534       * @param name the resource name
535       * @return an enumaration of all resources found
536       * @throws IOException if I/O errors occur in the process
537       * @since 1.2
538       */
539      public final Enumeration getResources(String name) throws IOException
540      {
541        Enumeration parentResources;
542        if (parent == null)
543          // XXX - Should use the bootstrap classloader
544          parentResources = EmptyEnumeration.getInstance();
545        else
546          parentResources = parent.getResources(name);
547        return new DoubleEnumeration(parentResources, findResources(name));
548      }
549    
550      /**
551       * Called whenever all locations of a named resource are needed.
552       * It is called by <code>getResources()</code> after it has called
553       * <code>parent.getResources()</code>. The results are combined by
554       * the <code>getResources()</code> method.
555       *
556       * <p>The default implementation always returns an empty Enumeration.
557       * Subclasses should override it when they can provide an Enumeration of
558       * URLs (possibly just one element) to the named resource.
559       * The first URL of the Enumeration should be the same as the one
560       * returned by <code>findResource</code>.
561       *
562       * @param name the name of the resource to be found
563       * @return a possibly empty Enumeration of URLs to the named resource
564       * @throws IOException if I/O errors occur in the process
565       * @since 1.2
566       */
567      protected Enumeration findResources(String name) throws IOException
568      {
569        return EmptyEnumeration.getInstance();
570      }
571    
572      /**
573       * Called whenever a resource is needed that could not be provided by
574       * one of the parents of this classloader. It is called by
575       * <code>getResource()</code> after <code>parent.getResource()</code>
576       * couldn't provide the requested resource.
577       *
578       * <p>The default implementation always returns null. Subclasses should
579       * override this method when they can provide a way to return a URL
580       * to a named resource.
581       *
582       * @param name the name of the resource to be found
583       * @return a URL to the named resource or null when not found
584       * @since 1.2
585       */
586      protected URL findResource(String name)
587      {
588        return null;
589      }
590    
591      /**
592       * Get the URL to a resource using the system classloader.
593       *
594       * @param name the name of the resource relative to the system classloader
595       * @return the URL to the resource
596       * @since 1.1
597       */
598      public static final URL getSystemResource(String name)
599      {
600        //XXX This should be:
601        // return getSystemClassLoader().getResource(name);
602        if (name.startsWith("/"))
603          name = name.substring(1);
604        String cp = System.getProperty("java.class.path");
605        if (cp == null)
606          return null;
607    
608        StringTokenizer st = new StringTokenizer(cp, File.pathSeparator);
609        while (st.hasMoreTokens())
610          {
611            String path = st.nextToken();
612            if (path.toLowerCase().endsWith(".zip") ||
613                path.toLowerCase().endsWith(".jar"))
614              return null; // Not implemented yet
615            File f;
616            if (path.endsWith(File.separator))
617              f = new File(path + name);
618          else          else
619              parentResources = parent.getResources(name);            f = new File(path + File.separator + name);
620    
621          return new DoubleEnumeration(parentResources, findResources(name));          if (f.exists())
622      }            try
623                {
624      /**                return new URL("file://" + f.getAbsolutePath());
625       * Called by <code>Runtime.loadLibrary()</code> to get an absolute path              }
626       * to a (system specific) library that was requested by a class loaded            catch (MalformedURLException e)
627       * by this classloader. The default implementation returns              {
628       * <code>null</code>. It should be implemented by subclasses when they                return null;
629       * have a way to find the absolute path to a library. If this method              }
630       * returns null the library is searched for in the default locations        }
631       * (the directories listed in the <code>java.library.path</code> system      return null;
632       * property).    }
633       *  
634       * @param name the (system specific) name of the requested library.    /**
635       * @return the full pathname to the requested library     * Get an Enumeration of URLs to resources with a given name using the
636       * or null when not found     * the system classloader. The enumeration firsts lists the resources with
637       *     * the given name that can be found by the bootstrap classloader followed
638       * @see Runtime#loadLibrary()     * by the resources with the given name that can be found on the classpath.
639       * @since 1.2     *
640       */     * @param name the name of the resource relative to the system classloader
641      protected String findLibrary(String name)     * @return an Enumeration of URLs to the resources
642      {     * @throws IOException if I/O errors occur in the process
643       * @since 1.2
644       */
645      public static Enumeration getSystemResources(String name) throws IOException
646      {
647        // XXX should be
648        // return getSystemClassLoader().getResources(name);
649        return systemClassLoader.getResources(name);
650      }
651    
652      /**
653       * Get a resource as stream using this classloader or one of its parents.
654       * First calls <code>getResource()</code> and if that returns a URL to
655       * the resource then it calls and returns the InputStream given by
656       * <code>URL.openStream()</code>.
657       *
658       * <p>Subclasses should not override this method but should override
659       * <code>findResource()</code> which is called by this method.
660       *
661       * @param name the name of the resource relative to this classloader
662       * @return an InputStream to the resource, or null
663       * @since 1.1
664       */
665      public InputStream getResourceAsStream(String name)
666      {
667        URL url = getResource(name);
668        if (url == null)
669          return null;
670        try
671          {
672            return url.openStream();
673          }
674        catch(IOException e)
675          {
676          return null;          return null;
677      }        }
678      }
679    
680      /** Get an Enumeration of URLs to resources with a given name using    /**
681       ** the system classloader. The enumeration firsts lists the resources     * Get a resource using the system classloader.
682       ** with the given name that can be found by the bootstrap classloader     *
683       ** followed by the resources with the given name that can be found     * @param name the name of the resource relative to the system classloader
684       ** on the classpath.     * @return an input stream for the resource, or null
685       ** @param name the name of the resource relative to the     * @since 1.1
686       **        system classloader.     */
687       ** @return an Enumeration of URLs to the resources.    public static final InputStream getSystemResourceAsStream(String name)
688       **    {
689       ** @since 1.2      try
690       **/        {
691      public static Enumeration getSystemResources(String name)          URL url = getSystemResource(name);
692          throws IOException          if (url == null)
693      {            return null;
694          return systemClassLoader.getResources(name);          return url.openStream();
695      }        }
696        catch(IOException e)
697          {
698            return null;
699          }
700      }
701    
702      /**
703       * Returns the system classloader. The system classloader (also called
704       * the application classloader) is the classloader that was used to
705       * load the application classes on the classpath (given by the system
706       * property <code>java.class.path</code>. This is set as the context
707       * class loader for a thread. The system property
708       * <code>java.system.class.loader</code>, if defined, is taken to be the
709       * name of the class to use as the system class loader, otherwise this
710       * uses gnu.java.lang.SystemClassLoader.
711       *
712       * <p>Note that this is different from the bootstrap classloader that
713       * actually loads all the real "system" classes (the bootstrap classloader
714       * is the parent of the returned system classloader).
715       *
716       * <p>A security check will be performed for
717       * <code>RuntimePermission("getClassLoader")</code> if the calling class
718       * is not a parent of the system class loader.
719       *
720       * @return the system class loader
721       * @throws SecurityException if the security check fails
722       * @throws IllegalStateException if this is called recursively
723       * @throws Error if <code>java.system.class.loader</code> fails to load
724       * @since 1.2
725       */
726      public static ClassLoader getSystemClassLoader()
727      {
728        //XXX This needs to check for java.system.class.loader.
729        // Check if we may return the system classloader
730        SecurityManager sm = System.getSecurityManager();
731        if (sm != null)
732          {
733            Class c = VMSecurityManager.getClassContext()[1];
734            ClassLoader cl = c.getClassLoader();
735            if (cl != null && cl != systemClassLoader)
736              sm.checkPermission(new RuntimePermission("getClassLoader"));
737          }
738        return systemClassLoader;
739      }
740    
741      /**
742       * Defines a new package and creates a Package object. The package should
743       * be defined before any class in the package is defined with
744       * <code>defineClass()</code>. The package should not yet be defined
745       * before in this classloader or in one of its parents (which means that
746       * <code>getPackage()</code> should return <code>null</code>). All
747       * parameters except the <code>name</code> of the package may be
748       * <code>null</code>.
749       *
750       * <p>Subclasses should call this method from their <code>findClass()</code>
751       * implementation before calling <code>defineClass()</code> on a Class
752       * in a not yet defined Package (which can be checked by calling
753       * <code>getPackage()</code>).
754       *
755       * @param name the name of the Package
756       * @param specTitle the name of the specification
757       * @param specVendor the name of the specification designer
758       * @param specVersion the version of this specification
759       * @param implTitle the name of the implementation
760       * @param implVendor the vendor that wrote this implementation
761       * @param implVersion the version of this implementation
762       * @param sealed if sealed the origin of the package classes
763       * @return the Package object for the specified package
764       * @throws IllegalArgumentException if the package name is null or it
765       *         was already defined by this classloader or one of its parents
766       * @see Package
767       * @since 1.2
768       */
769      protected Package definePackage(String name, String specTitle,
770                                      String specVendor, String specVersion,
771                                      String implTitle, String implVendor,
772                                      String implVersion, URL sealed)
773      {
774        if (getPackage(name) != null)
775          throw new IllegalArgumentException("Package " + name
776                                             + " already defined");
777        Package p = new Package(name, specTitle, specVendor, specVersion,
778                                implTitle, implVendor, implVersion, sealed);
779        definedPackages.put(name, p);
780        return p;
781      }
782    
783      /**
784       * Returns the Package object for the requested package name. It returns
785       * null when the package is not defined by this classloader or one of its
786       * parents.
787       *
788       * @param name the package name to find
789       * @return the package, if defined
790       * @since 1.2
791       */
792      protected final Package getPackage(String name)
793      {
794        Package p;
795        if (parent == null)
796          // XXX - Should we use the bootstrap classloader?
797          p = null;
798        else
799          p = parent.getPackage(name);
800    
801        if (p == null)
802          p = (Package)definedPackages.get(name);
803        return p;
804      }
805    
806      /**
807       * Returns all Package objects defined by this classloader and its parents.
808       *
809       * @return an array of all defined packages
810       * @since 1.2
811       */
812      protected Package[] getPackages()
813      {
814        Package[] allPackages;
815    
816        // Get all our packages.
817        Package[] packages;
818        synchronized(definedPackages)
819          {
820            packages = new Package[definedPackages.size()];
821            Enumeration e = definedPackages.elements();
822            int i = 0;
823            while (e.hasMoreElements())
824              {
825                packages[i] = (Package)e.nextElement();
826                i++;
827              }
828          }
829    
830        // If we have a parent get all packages defined by our parents.
831        if (parent != null)
832          {
833            Package[] parentPackages = parent.getPackages();
834            allPackages = new Package[parentPackages.length + packages.length];
835            System.arraycopy(parentPackages, 0, allPackages, 0,
836                             parentPackages.length);
837            System.arraycopy(packages, 0, allPackages, parentPackages.length,
838                             packages.length);
839          } else
840            // XXX - Should we use the bootstrap classloader?
841            allPackages = packages;
842    
843        return allPackages;
844      }
845    
846      /**
847       * Called by <code>Runtime.loadLibrary()</code> to get an absolute path
848       * to a (system specific) library that was requested by a class loaded
849       * by this classloader. The default implementation returns
850       * <code>null</code>. It should be implemented by subclasses when they
851       * have a way to find the absolute path to a library. If this method
852       * returns null the library is searched for in the default locations
853       * (the directories listed in the <code>java.library.path</code> system
854       * property).
855       *
856       * @param name the (system specific) name of the requested library
857       * @return the full pathname to the requested library, or null
858       * @see Runtime#loadLibrary()
859       * @since 1.2
860       */
861      protected String findLibrary(String name)
862      {
863        return null;
864      }
865    
866      /**
867       * Set the default assertion status for classes loaded by this classloader,
868       * used unless overridden by a package or class request.
869       *
870       * @param enabled true to set the default to enabled
871       * @see #setClassAssertionStatus(String, boolean)
872       * @see #setPackageAssertionStatus(String, boolean)
873       * @see #clearAssertionStatus()
874       * @since 1.4
875       * @XXX Implement for 1.4 compatibility.
876      public void setDefaultAssertionStatus(boolean enabled)
877      {
878        defaultAssertionStatus = enabled;
879      }
880       */
881      
882      /**
883       * Set the default assertion status for packages, used unless overridden
884       * by a class request. This default also covers subpackages, unless they
885       * are also specified. The unnamed package should use null for the name.
886       *
887       * @param name the package (and subpackages) to affect
888       * @param enabled true to set the default to enabled
889       * @see #setDefaultAssertionStatus(String, boolean)
890       * @see #setClassAssertionStatus(String, boolean)
891       * @see #clearAssertionStatus()
892       * @since 1.4
893       * @XXX Implement for 1.4 compatibility.
894      public synchronized void setPackageAssertionStatus(String name,
895                                                         boolean enabled)
896      {
897        if (packageAssertionStatus == null)
898          packageAssertionStatus
899            = new HashMap(systemPackageAssertionStatus);
900        packageAssertionStatus.put(name, Boolean.valueOf(enabled));
901      }
902       */
903      
904      /**
905       * Set the default assertion status for a class. This only affects the
906       * status of top-level classes, any other string is harmless.
907       *
908       * @param name the class to affect
909       * @param enabled true to set the default to enabled
910       * @throws NullPointerException if name is null
911       * @see #setDefaultAssertionStatus(String, boolean)
912       * @see #setPackageAssertionStatus(String, boolean)
913       * @see #clearAssertionStatus()
914       * @since 1.4
915       * @XXX Implement for 1.4 compatibility.
916      public synchronized void setClassAssertionStatus(String name,
917                                                       boolean enabled)
918      {
919        if (classAssertionStatus == null)
920          classAssertionStatus = new HashMap(systemClassAssertionStatus);
921        // The toString() hack catches null, as required.
922        classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled));
923      }
924       */
925      
926      /**
927       * Resets the default assertion status of this classloader, its packages
928       * and classes, all to false. This allows overriding defaults inherited
929       * from the command line.
930       *
931       * @see #setDefaultAssertionStatus(boolean)
932       * @see #setClassAssertionStatus(String, boolean)
933       * @see #setPackageAssertionStatus(String, boolean)
934       * @since 1.4
935       * @XXX Implement for 1.4 compatibility.
936      public synchronized void clearAssertionStatus()
937      {
938        defaultAssertionStatus = false;
939        packageAssertionStatus = new HashMap();
940        classAssertionStatus = new HashMap();
941      }
942       */
943      
944  }  }
945    

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26