OSDN Git Service

* java/lang/ClassLoader.java (findLoadedClass): Removed erroneous
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / ClassLoader.java
1 // ClassLoader.java - Define policies for loading Java classes.
2
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 package java.lang;
12
13 import java.io.InputStream;
14 import java.io.IOException;
15 import java.net.URL;
16 import java.security.AllPermission;
17 import java.security.CodeSource;
18 import java.security.Permission;
19 import java.security.Permissions;
20 import java.security.Policy;
21 import java.security.ProtectionDomain;
22 import java.util.*;
23
24 /**
25  * The ClassLoader is a way of customizing the way Java gets its classes
26  * and loads them into memory.  The verifier and other standard Java things
27  * still run, but the ClassLoader is allowed great flexibility in determining
28  * where to get the classfiles and when to load and resolve them. For that
29  * matter, a custom ClassLoader can perform on-the-fly code generation or
30  * modification!
31  *
32  * <p>Every classloader has a parent classloader that is consulted before
33  * the 'child' classloader when classes or resources should be loaded.   
34  * This is done to make sure that classes can be loaded from an hierarchy of
35  * multiple classloaders and classloaders do not accidentially redefine   
36  * already loaded classes by classloaders higher in the hierarchy.
37  *   
38  * <p>The grandparent of all classloaders is the bootstrap classloader, which
39  * loads all the standard system classes as implemented by GNU Classpath. The
40  * other special classloader is the system classloader (also called
41  * application classloader) that loads all classes from the CLASSPATH
42  * (<code>java.class.path</code> system property). The system classloader
43  * is responsible for finding the application classes from the classpath,
44  * and delegates all requests for the standard library classes to its parent
45  * the bootstrap classloader. Most programs will load all their classes
46  * through the system classloaders.
47  *
48  * <p>The bootstrap classloader in GNU Classpath is implemented as a couple of
49  * static (native) methods on the package private class
50  * <code>java.lang.VMClassLoader</code>, the system classloader is an
51  * instance of <code>gnu.java.lang.SystemClassLoader</code>
52  * (which is a subclass of <code>java.net.URLClassLoader</code>).
53  *
54  * <p>Users of a <code>ClassLoader</code> will normally just use the methods
55  * <ul>
56  *  <li> <code>loadClass()</code> to load a class.</li>
57  *  <li> <code>getResource()</code> or <code>getResourceAsStream()</code>
58  *       to access a resource.</li>
59  *  <li> <code>getResources()</code> to get an Enumeration of URLs to all
60  *       the resources provided by the classloader and its parents with the
61  *       same name.</li>
62  * </ul>
63  *
64  * <p>Subclasses should implement the methods
65  * <ul>
66  *  <li> <code>findClass()</code> which is called by <code>loadClass()</code>
67  *       when the parent classloader cannot provide a named class.</li>
68  *  <li> <code>findResource()</code> which is called by
69  *       <code>getResource()</code> when the parent classloader cannot provide
70  *       a named resource.</li>
71  *  <li> <code>findResources()</code> which is called by
72  *       <code>getResource()</code> to combine all the resources with the
73  *       same name from the classloader and its parents.</li>
74  *  <li> <code>findLibrary()</code> which is called by
75  *       <code>Runtime.loadLibrary()</code> when a class defined by the
76  *       classloader wants to load a native library.</li>
77  * </ul>
78  *
79  * @author John Keiser
80  * @author Mark Wielaard
81  * @author Eric Blake
82  * @author Kresten Krab Thorup
83  * @see Class
84  * @since 1.0
85  * @status still missing 1.4 functionality
86  */
87 public abstract class ClassLoader
88 {
89   /**
90    * All classes loaded by this classloader. VM's may choose to implement
91    * this cache natively; but it is here available for use if necessary. It
92    * is not private in order to allow native code (and trusted subclasses)
93    * access to this field.
94    */
95   final Map loadedClasses = new HashMap();
96
97   /**
98    * The desired assertion status of classes loaded by this loader, if not
99    * overridden by package or class instructions.
100    */
101   // Package visible for use by Class.
102   boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus();
103
104   /**
105    * The command-line state of the package assertion status overrides. This
106    * map is never modified, so it does not need to be synchronized.
107    */
108   // Package visible for use by Class.
109   static final Map systemPackageAssertionStatus
110     = VMClassLoader.packageAssertionStatus();
111
112   /**
113    * The map of package assertion status overrides, or null if no package
114    * overrides have been specified yet. The values of the map should be
115    * Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented
116    * by the null key. This map must be synchronized on this instance.
117    */
118   // Package visible for use by Class.
119   Map packageAssertionStatus;
120
121   /**
122    * The command-line state of the class assertion status overrides. This
123    * map is never modified, so it does not need to be synchronized.
124    */
125   // Package visible for use by Class.
126   static final Map systemClassAssertionStatus
127     = VMClassLoader.classAssertionStatus();
128
129   /**
130    * The map of class assertion status overrides, or null if no class
131    * overrides have been specified yet. The values of the map should be
132    * Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this
133    * instance.
134    */
135   // Package visible for use by Class.
136   Map classAssertionStatus;
137
138   /**
139    * The classloader that is consulted before this classloader.
140    * If null then the parent is the bootstrap classloader.
141    */
142   private final ClassLoader parent;
143
144   /**
145    * All packages defined by this classloader. It is not private in order to
146    * allow native code (and trusted subclasses) access to this field.
147    */
148   private HashMap definedPackages = new HashMap();
149
150   /**
151    * Returns the parent of this classloader. If the parent of this
152    * classloader is the bootstrap classloader then this method returns
153    * <code>null</code>. A security check may be performed on
154    * <code>RuntimePermission("getClassLoader")</code>.
155    *
156    * @throws SecurityException if the security check fails
157    * @since 1.2
158    */
159   public final ClassLoader getParent ()
160   {
161     // Check if we may return the parent classloader
162     SecurityManager sm = System.getSecurityManager();
163     if (sm != null)
164       {
165         /* FIXME: security, getClassContext() not implemented.
166         Class c = VMSecurityManager.getClassContext()[1];
167         ClassLoader cl = c.getClassLoader();
168         if (cl != null && cl != this)
169           sm.checkPermission(new RuntimePermission("getClassLoader"));
170         */
171       }
172     return parent;
173   }
174
175   /**
176    * Returns the system classloader. The system classloader (also called
177    * the application classloader) is the classloader that was used to
178    * load the application classes on the classpath (given by the system
179    * property <code>java.class.path</code>. This is set as the context
180    * class loader for a thread. The system property
181    * <code>java.system.class.loader</code>, if defined, is taken to be the
182    * name of the class to use as the system class loader, which must have
183    * a public constructor which takes a ClassLoader as a parent; otherwise this
184    * uses gnu.java.lang.SystemClassLoader.
185    *
186    * <p>Note that this is different from the bootstrap classloader that
187    * actually loads all the real "system" classes (the bootstrap classloader
188    * is the parent of the returned system classloader).
189    *
190    * <p>A security check will be performed for
191    * <code>RuntimePermission("getClassLoader")</code> if the calling class
192    * is not a parent of the system class loader.
193    *
194    * @return the system class loader
195    * @throws SecurityException if the security check fails
196    * @throws IllegalStateException if this is called recursively
197    * @throws Error if <code>java.system.class.loader</code> fails to load
198    * @since 1.2
199    */
200   public static ClassLoader getSystemClassLoader ()
201   {
202     return gnu.gcj.runtime.VMClassLoader.instance;
203   }
204
205   /**
206    * Creates a <code>ClassLoader</code> with no parent.
207    * @exception java.lang.SecurityException if not allowed
208    */
209   protected ClassLoader() 
210   {
211     this (null);
212   }
213
214   /**
215    * Creates a <code>ClassLoader</code> with the given parent.   
216    * The parent may be <code>null</code>.
217    * The only thing this 
218    * constructor does, is to call
219    * <code>checkCreateClassLoader</code> on the current 
220    * security manager. 
221    * @exception java.lang.SecurityException if not allowed
222    * @since 1.2
223    */
224   protected ClassLoader(ClassLoader parent) 
225   {
226     SecurityManager security = System.getSecurityManager ();
227     if (security != null)
228       security.checkCreateClassLoader ();
229     this.parent = parent;
230   }
231
232   /** 
233    * Loads and link the class by the given name.
234    * @param     name the name of the class.
235    * @return    the class loaded.
236    * @see       ClassLoader#loadClass(String,boolean)
237    * @exception java.lang.ClassNotFoundException 
238    */ 
239   public Class loadClass(String name)
240     throws java.lang.ClassNotFoundException
241   { 
242     return loadClass (name, false);
243   }
244   
245   /** 
246    * Loads the class by the given name.  The default implementation
247    * will search for the class in the following order (similar to jdk 1.2)
248    * <ul>
249    *  <li> First <code>findLoadedClass</code>.
250    *  <li> If parent is non-null, <code>parent.loadClass</code>;
251    *       otherwise <code>findSystemClass</code>.
252    *  <li> <code>findClass</code>.
253    * </ul>
254    * If <code>link</code> is true, <code>resolveClass</code> is then
255    * called.  <p> Normally, this need not be overridden; override
256    * <code>findClass</code> instead.
257    * @param     name the name of the class.
258    * @param     link if the class should be linked.
259    * @return    the class loaded.
260    * @exception java.lang.ClassNotFoundException 
261    * @deprecated 
262    */ 
263   protected Class loadClass(String name, boolean link)
264     throws java.lang.ClassNotFoundException
265   {
266     Class c = findLoadedClass (name);
267
268     if (c == null)
269       {
270         try
271           {
272             ClassLoader cl = parent;
273             if (parent == null)
274               cl = gnu.gcj.runtime.VMClassLoader.instance;
275             if (cl != this)
276               c = cl.loadClass (name, link);
277           }
278         catch (ClassNotFoundException ex)
279           {
280             /* ignore, we'll try findClass */;
281           }
282       }
283
284     if (c == null)
285       c = findClass (name);
286
287     if (c == null)
288       throw new ClassNotFoundException (name);
289
290     if (link)
291       resolveClass (c);
292
293     return c;
294   }
295
296   /**
297    * Called for every class name that is needed but has not yet been
298    * defined by this classloader or one of its parents. It is called by
299    * <code>loadClass()</code> after both <code>findLoadedClass()</code> and
300    * <code>parent.loadClass()</code> couldn't provide the requested class.
301    *
302    * <p>The default implementation throws a
303    * <code>ClassNotFoundException</code>. Subclasses should override this
304    * method. An implementation of this method in a subclass should get the
305    * class bytes of the class (if it can find them), if the package of the
306    * requested class doesn't exist it should define the package and finally
307    * it should call define the actual class. It does not have to resolve the
308    * class. It should look something like the following:<br>
309    *
310    * <pre>
311    * // Get the bytes that describe the requested class
312    * byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name);
313    * // Get the package name
314    * int lastDot = name.lastIndexOf('.');
315    * if (lastDot != -1)
316    *   {
317    *     String packageName = name.substring(0, lastDot);
318    *     // Look if the package already exists
319    *     if (getPackage(pkg) == null)
320    *       {
321    *         // define the package
322    *         definePackage(packageName, ...);
323    *       }
324    *   }
325    * // Define and return the class
326    *  return defineClass(name, classBytes, 0, classBytes.length);
327    * </pre>
328    *
329    * <p><code>loadClass()</code> makes sure that the <code>Class</code>
330    * returned by <code>findClass()</code> will later be returned by
331    * <code>findLoadedClass()</code> when the same class name is requested.
332    *
333    * @param name class name to find (including the package name)
334    * @return the requested Class
335    * @throws ClassNotFoundException when the class can not be found
336    * @since 1.2
337    */   
338   protected Class findClass (String name)
339     throws ClassNotFoundException
340   {
341     throw new ClassNotFoundException (name);
342   }
343
344   // Protection Domain definitions 
345   // FIXME: should there be a special protection domain used for native code?
346   
347   // The permission required to check what a classes protection domain is.
348   static final Permission protectionDomainPermission
349     = new RuntimePermission("getProtectionDomain");
350   // The protection domain returned if we cannot determine it. 
351   static ProtectionDomain unknownProtectionDomain;
352   // Protection domain to use when a class is defined without one specified.
353   static ProtectionDomain defaultProtectionDomain;
354
355   static
356   {
357     Permissions permissions = new Permissions();
358     permissions.add(new AllPermission());
359     unknownProtectionDomain = new ProtectionDomain(null, permissions);  
360
361     CodeSource cs = new CodeSource(null, null);
362     defaultProtectionDomain =
363       new ProtectionDomain(cs, Policy.getPolicy().getPermissions(cs));
364   }
365
366   /** 
367    * Defines a class, given the class-data.  According to the JVM, this
368    * method should not be used; instead use the variant of this method
369    * in which the name of the class being defined is specified
370    * explicitly.   
371    * <P>
372    * If the name of the class, as specified (implicitly) in the class
373    * data, denotes a class which has already been loaded by this class
374    * loader, an instance of
375    * <code>java.lang.ClassNotFoundException</code> will be thrown.
376    *
377    * @param     data    bytes in class file format.
378    * @param     off     offset to start interpreting data.
379    * @param     len     length of data in class file.
380    * @return    the class defined.
381    * @exception java.lang.ClassNotFoundException 
382    * @exception java.lang.LinkageError
383    * @see ClassLoader#defineClass(String,byte[],int,int) */
384   protected final Class defineClass(byte[] data, int off, int len) 
385     throws ClassFormatError
386   {
387     return defineClass (null, data, off, len, defaultProtectionDomain);
388   }
389
390   /**
391    * Helper to define a class using a string of bytes without a
392    * ProtectionDomain. Subclasses should call this method from their
393    * <code>findClass()</code> implementation. The name should use '.'
394    * separators, and discard the trailing ".class".  The default protection
395    * domain has the permissions of
396    * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))<code>.
397    *
398    * @param name the name to give the class, or null if unknown
399    * @param data the data representing the classfile, in classfile format
400    * @param offset the offset into the data where the classfile starts
401    * @param len the length of the classfile data in the array
402    * @return the class that was defined
403    * @throws ClassFormatError if data is not in proper classfile format
404    * @throws IndexOutOfBoundsException if offset or len is negative, or
405    *         offset + len exceeds data
406    * @throws SecurityException if name starts with "java."
407    * @since 1.1
408    */
409   protected final Class defineClass(String name, byte[] data, int off, int len)
410     throws ClassFormatError
411   {
412     return defineClass (name, data, off, len, defaultProtectionDomain);
413   }
414   
415   /** 
416    * Defines a class, given the class-data.  This is preferable
417    * over <code>defineClass(byte[],off,len)</code> since it is more
418    * secure.  If the expected name does not match that of the class
419    * file, <code>ClassNotFoundException</code> is thrown.  If
420    * <code>name</code> denotes the name of an already loaded class, a
421    * <code>LinkageError</code> is thrown.
422    * <p>
423    * 
424    * FIXME: How do we assure that the class-file data is not being
425    * modified, simultaneously with the class loader running!?  If this
426    * was done in some very clever way, it might break security.  
427    * Right now I am thinking that defineclass should make sure never to
428    * read an element of this array more than once, and that that would
429    * assure the ``immutable'' appearance.  It is still to be determined
430    * if this is in fact how defineClass operates.
431    *
432    * @param     name    the expected name.
433    * @param     data    bytes in class file format.
434    * @param     off     offset to start interpreting data.
435    * @param     len     length of data in class file.
436    * @param     protectionDomain security protection domain for the class.
437    * @return    the class defined.
438    * @exception java.lang.ClassNotFoundException 
439    * @exception java.lang.LinkageError
440    */
441   protected final synchronized Class defineClass(String name,
442                                                  byte[] data,
443                                                  int off,
444                                                  int len,
445                                                  ProtectionDomain protectionDomain)
446     throws ClassFormatError
447   {
448     if (data==null || data.length < off+len || off<0 || len<0)
449       throw new ClassFormatError ("arguments to defineClass "
450                                   + "are meaningless");
451
452     // as per 5.3.5.1
453     if (name != null && findLoadedClass (name) != null)
454       throw new java.lang.LinkageError ("class " 
455                                         + name 
456                                         + " already loaded");
457
458     if (protectionDomain == null)
459       protectionDomain = defaultProtectionDomain;
460
461     try
462       {
463         Class retval = defineClass0 (name, data, off, len, protectionDomain);
464         loadedClasses.put(retval.getName(), retval);
465         return retval;
466       }
467     catch (LinkageError x)
468       {
469         throw x;                // rethrow
470       }
471     catch (VirtualMachineError x)
472       {
473         throw x;                // rethrow
474       }
475     catch (Throwable x)
476       {
477         // This should never happen, or we are beyond spec.  
478         InternalError r = new InternalError ("Unexpected exception "
479                                              + "while defining class "
480                                              + name);
481         r.initCause(x);
482         throw r;
483       }
484   }
485
486   /** This is the entry point of defineClass into the native code */
487   private native Class defineClass0 (String name,
488                                      byte[] data,
489                                      int off,
490                                      int len,
491                                      ProtectionDomain protectionDomain)
492     throws ClassFormatError;
493
494   /** 
495    * Link the given class.  This will bring the class to a state where
496    * the class initializer can be run.  Linking involves the following
497    * steps: 
498    * <UL>
499    * <LI>  Prepare (allocate and internalize) the constant strings that
500    *       are used in this class.
501    * <LI>  Allocate storage for static fields, and define the layout
502    *       of instance fields.
503    * <LI>  Perform static initialization of ``static final'' int,
504    *       long, float, double and String fields for which there is a
505    *       compile-time constant initializer.
506    * <LI>  Create the internal representation of the ``vtable''.
507    * </UL>
508    * For <code>gcj</code>-compiled classes, only the first step is
509    * performed.  The compiler will have done the rest already.
510    * <P>
511    * This is called by the system automatically,
512    * as part of class initialization; there is no reason to ever call
513    * this method directly.  
514    * <P> 
515    * For historical reasons, this method has a name which is easily
516    * misunderstood.  Java classes are never ``resolved''.  Classes are
517    * linked; whereas method and field references are resolved.
518    *
519    * @param     clazz the class to link.
520    * @exception java.lang.LinkageError
521    */
522   protected final void resolveClass(Class clazz)
523   {
524     resolveClass0(clazz);
525   }
526
527   static void resolveClass0(Class clazz)
528   {
529     synchronized (clazz)
530       {
531         try
532           {
533             linkClass0 (clazz);
534           }
535         catch (Throwable x)
536           {
537             markClassErrorState0 (clazz);
538
539             LinkageError e;
540             if (x instanceof LinkageError)
541               e = (LinkageError)x;
542             else if (x instanceof ClassNotFoundException)
543               {
544                 e = new NoClassDefFoundError("while resolving class: "
545                                              + clazz.getName());
546                 e.initCause (x);
547               }
548             else
549               {
550                 e = new LinkageError ("unexpected exception during linking: "
551                                       + clazz.getName());
552                 e.initCause (x);
553               }
554             throw e;
555           }
556       }
557   }
558
559   /** Internal method.  Calls _Jv_PrepareClass and
560    * _Jv_PrepareCompiledClass.  This is only called from resolveClass.  */ 
561   private static native void linkClass0(Class clazz);
562
563   /** Internal method.  Marks the given clazz to be in an erroneous
564    * state, and calls notifyAll() on the class object.  This should only
565    * be called when the caller has the lock on the class object.  */
566   private static native void markClassErrorState0(Class clazz);
567
568   /**
569    * Defines a new package and creates a Package object.
570    * The package should be defined before any class in the package is
571    * defined with <code>defineClass()</code>. The package should not yet
572    * be defined before in this classloader or in one of its parents (which
573    * means that <code>getPackage()</code> should return <code>null</code>).
574    * All parameters except the <code>name</code> of the package may be
575    * <code>null</code>.
576    * <p>
577    * Subclasses should call this method from their <code>findClass()</code>
578    * implementation before calling <code>defineClass()</code> on a Class
579    * in a not yet defined Package (which can be checked by calling
580    * <code>getPackage()</code>).
581    *
582    * @param name The name of the Package
583    * @param specTitle The name of the specification
584    * @param specVendor The name of the specification designer
585    * @param specVersion The version of this specification
586    * @param implTitle The name of the implementation
587    * @param implVendor The vendor that wrote this implementation
588    * @param implVersion The version of this implementation
589    * @param sealed If sealed the origin of the package classes
590    * @return the Package object for the specified package
591    *
592    * @exception IllegalArgumentException if the package name is null or if
593    * it was already defined by this classloader or one of its parents.
594    *
595    * @see Package
596    * @since 1.2
597    */
598   protected Package definePackage(String name,
599                                   String specTitle, String specVendor,
600                                   String specVersion, String implTitle,
601                                   String implVendor, String implVersion,
602                                   URL sealed)
603   {
604     if (getPackage(name) != null)
605       throw new IllegalArgumentException("Package " + name
606                                          + " already defined");
607     Package p = new Package(name,
608                             specTitle, specVendor, specVersion,
609                             implTitle, implVendor, implVersion,
610                             sealed);
611     synchronized (definedPackages)
612     {
613       definedPackages.put(name, p);
614     }
615     return p;
616   }
617
618   /**
619    * Returns the Package object for the requested package name. It returns
620    * null when the package is not defined by this classloader or one of its
621    * parents.
622    *
623    * @param name the package name to find
624    * @return the package, if defined
625    * @since 1.2
626    */
627   protected Package getPackage(String name)
628   {
629     Package p;
630     if (parent == null)
631       // XXX - Should we use the bootstrap classloader?
632       p = null;
633     else
634       p = parent.getPackage(name);
635
636     if (p == null)
637       {
638         synchronized (definedPackages)
639         {
640           p = (Package) definedPackages.get(name);
641         }
642       }
643
644     return p;
645   }
646
647   /**
648    * Returns all Package objects defined by this classloader and its parents.
649    *
650    * @return an array of all defined packages
651    * @since 1.2
652    */
653   protected Package[] getPackages()
654   {
655     Package[] allPackages;
656
657     // Get all our packages.
658     Package[] packages;
659     synchronized(definedPackages)
660     {
661       packages = new Package[definedPackages.size()];
662       definedPackages.values().toArray(packages);
663     }
664
665     // If we have a parent get all packages defined by our parents.
666     if (parent != null)
667       {
668         Package[] parentPackages = parent.getPackages();
669         allPackages = new Package[parentPackages.length + packages.length];
670         System.arraycopy(parentPackages, 0, allPackages, 0,
671                          parentPackages.length);
672         System.arraycopy(packages, 0, allPackages, parentPackages.length,
673                          packages.length);
674       }
675     else
676       // XXX - Should we use the bootstrap classloader?
677       allPackages = packages;
678
679     return allPackages;
680   }
681
682   /**
683    * Called by <code>Runtime.loadLibrary()</code> to get an absolute path
684    * to a (system specific) library that was requested by a class loaded
685    * by this classloader. The default implementation returns
686    * <code>null</code>. It should be implemented by subclasses when they
687    * have a way to find the absolute path to a library. If this method
688    * returns null the library is searched for in the default locations
689    * (the directories listed in the <code>java.library.path</code> system
690    * property).
691    *
692    * @param name the (system specific) name of the requested library
693    * @return the full pathname to the requested library, or null
694    * @see Runtime#loadLibrary()
695    * @since 1.2
696    */
697   protected String findLibrary(String name)
698   {
699     return null;
700   }
701
702   /** 
703    * Returns a class found in a system-specific way, typically
704    * via the <code>java.class.path</code> system property.  Loads the 
705    * class if necessary.
706    *
707    * @param     name the class to resolve.
708    * @return    the class loaded.
709    * @exception java.lang.LinkageError 
710    * @exception java.lang.ClassNotFoundException 
711    */
712   protected final Class findSystemClass(String name) 
713     throws java.lang.ClassNotFoundException
714   {
715     return gnu.gcj.runtime.VMClassLoader.instance.loadClass (name);
716   }
717
718   /**
719    * Helper to set the signers of a class. This should be called after
720    * defining the class.
721    *
722    * @param c the Class to set signers of
723    * @param signers the signers to set
724    * @since 1.1
725    */   
726   protected final void setSigners(Class c, Object[] signers)
727   {
728     /*
729      * Does currently nothing. FIXME.
730      */ 
731   }
732
733   /**
734    * If a class named <code>name</code> was previously loaded using
735    * this <code>ClassLoader</code>, then it is returned.  Otherwise
736    * it returns <code>null</code>.
737    * @param     name  class to find.
738    * @return    the class loaded, or null.
739    */ 
740   protected final synchronized Class findLoadedClass(String name)
741   {
742     return (Class) loadedClasses.get(name);
743   }
744
745   /**
746    * Get a resource using the system classloader.
747    *
748    * @param name the name of the resource relative to the system classloader
749    * @return an input stream for the resource, or null
750    * @since 1.1
751    */
752   public static InputStream getSystemResourceAsStream(String name) {
753     return getSystemClassLoader().getResourceAsStream (name);
754   }
755
756   /**
757    * Get the URL to a resource using the system classloader.
758    *
759    * @param name the name of the resource relative to the system classloader
760    * @return the URL to the resource
761    * @since 1.1
762    */
763   public static URL getSystemResource(String name) {
764     return getSystemClassLoader().getResource (name);
765   }
766
767   /**
768    * Get an Enumeration of URLs to resources with a given name using the
769    * the system classloader. The enumeration firsts lists the resources with
770    * the given name that can be found by the bootstrap classloader followed
771    * by the resources with the given name that can be found on the classpath.
772    *
773    * @param name the name of the resource relative to the system classloader
774    * @return an Enumeration of URLs to the resources
775    * @throws IOException if I/O errors occur in the process
776    * @since 1.2
777    */
778   public static Enumeration getSystemResources(String name) throws IOException
779   {
780     return getSystemClassLoader().getResources(name);
781   }
782
783   /**
784    *   Return an InputStream representing the resource name.  
785    *   This is essentially like 
786    *   <code>getResource(name).openStream()</code>, except
787    *   it masks out any IOException and returns null on failure.
788    * @param   name  resource to load
789    * @return  an InputStream, or null
790    * @see     java.lang.ClassLoader#getResource(String)
791    * @see     java.io.InputStream
792    */
793   public InputStream getResourceAsStream(String name) 
794   {
795     try
796       {
797         URL res = getResource (name);
798         if (res == null)
799           return null;
800         return res.openStream ();
801       }
802     catch (java.io.IOException x)
803       {
804         return null;
805       }
806   }
807  
808   /**
809    * Return an java.io.URL representing the resouce <code>name</code>.  
810    * The default implementation just returns <code>null</code>.
811    * @param   name  resource to load
812    * @return  a URL, or null if there is no such resource.
813    * @see     java.lang.ClassLoader#getResourceAsBytes(String)
814    * @see     java.lang.ClassLoader#getResourceAsStream(String)
815    * @see     java.io.URL
816    */
817   public URL getResource (String name) 
818   {
819     // The rules say search the parent class if non-null,
820     // otherwise search the built-in class loader (assumed to be
821     // the system ClassLoader).  If not found, call
822     // findResource().
823     URL result = null;
824
825     ClassLoader delegate = parent;
826
827     if (delegate == null)
828       delegate = getSystemClassLoader ();
829         
830     // Protect ourselves from looping.
831     if (this != delegate)
832       result = delegate.getResource (name);
833
834     if (result != null)
835       return result;
836     else
837       return findResource (name);
838   }
839
840   /**
841    * Called whenever a resource is needed that could not be provided by
842    * one of the parents of this classloader. It is called by
843    * <code>getResource()</code> after <code>parent.getResource()</code>
844    * couldn't provide the requested resource.
845    *
846    * <p>The default implementation always returns null. Subclasses should
847    * override this method when they can provide a way to return a URL
848    * to a named resource.
849    *
850    * @param name the name of the resource to be found
851    * @return a URL to the named resource or null when not found
852    * @since 1.2
853    */
854   protected URL findResource (String name)
855   {
856     // Default to returning null.  Derived classes implement this.
857     return null;
858   }
859
860   /**
861    * Returns an Enumeration of all resources with a given name that can
862    * be found by this classloader and its parents. Certain classloaders
863    * (such as the URLClassLoader when given multiple jar files) can have
864    * multiple resources with the same name that come from multiple locations.
865    * It can also occur that a parent classloader offers a resource with a
866    * certain name and the child classloader also offers a resource with that
867    * same name. <code>getResource() only offers the first resource (of the
868    * parent) with a given name. This method lists all resources with the
869    * same name. The name should use '/' as path separators.
870    *
871    * <p>The Enumeration is created by first calling <code>getResources()</code>
872    * on the parent classloader and then calling <code>findResources()</code>
873    * on this classloader.
874    *
875    * @param name the resource name
876    * @return an enumaration of all resources found
877    * @throws IOException if I/O errors occur in the process
878    * @since 1.2
879    */
880   public final Enumeration getResources(String name) throws IOException
881   {
882     // The rules say search the parent class if non-null,
883     // otherwise search the built-in class loader (assumed to be
884     // the system ClassLoader).  If not found, call
885     // findResource().
886     Enumeration result = null;
887
888     ClassLoader delegate = parent;
889
890     if (delegate == null)
891       delegate = getSystemClassLoader ();
892         
893     // Protect ourselves from looping.
894     if (this != delegate)
895       result = delegate.getResources (name);
896
897     if (result != null)
898       return result;
899     else
900       return findResources (name);
901   }
902
903   /**
904    * Called whenever all locations of a named resource are needed.
905    * It is called by <code>getResources()</code> after it has called
906    * <code>parent.getResources()</code>. The results are combined by
907    * the <code>getResources()</code> method.
908    *
909    * <p>The default implementation always returns an empty Enumeration.
910    * Subclasses should override it when they can provide an Enumeration of
911    * URLs (possibly just one element) to the named resource.
912    * The first URL of the Enumeration should be the same as the one
913    * returned by <code>findResource</code>.
914    *
915    * @param name the name of the resource to be found
916    * @return a possibly empty Enumeration of URLs to the named resource
917    * @throws IOException if I/O errors occur in the process
918    * @since 1.2
919    */
920   protected Enumeration findResources(String name) throws IOException
921   {
922     return Collections.enumeration(Collections.EMPTY_LIST);
923   }
924
925   /**
926    * Set the default assertion status for classes loaded by this classloader,
927    * used unless overridden by a package or class request.
928    *
929    * @param enabled true to set the default to enabled
930    * @see #setClassAssertionStatus(String, boolean)
931    * @see #setPackageAssertionStatus(String, boolean)
932    * @see #clearAssertionStatus()
933    * @since 1.4
934    */
935   public void setDefaultAssertionStatus(boolean enabled)
936   {
937     defaultAssertionStatus = enabled;
938   }
939
940   /**
941    * Set the default assertion status for packages, used unless overridden
942    * by a class request. This default also covers subpackages, unless they
943    * are also specified. The unnamed package should use null for the name.
944    *
945    * @param name the package (and subpackages) to affect
946    * @param enabled true to set the default to enabled
947    * @see #setDefaultAssertionStatus(String, boolean)
948    * @see #setClassAssertionStatus(String, boolean)
949    * @see #clearAssertionStatus()
950    * @since 1.4
951    */
952   public synchronized void setPackageAssertionStatus(String name,
953                                                      boolean enabled)
954   {
955     if (packageAssertionStatus == null)
956       packageAssertionStatus
957         = new HashMap(systemPackageAssertionStatus);
958     packageAssertionStatus.put(name, Boolean.valueOf(enabled));
959   }
960   
961   /**
962    * Set the default assertion status for a class. This only affects the
963    * status of top-level classes, any other string is harmless.
964    *
965    * @param name the class to affect
966    * @param enabled true to set the default to enabled
967    * @throws NullPointerException if name is null
968    * @see #setDefaultAssertionStatus(String, boolean)
969    * @see #setPackageAssertionStatus(String, boolean)
970    * @see #clearAssertionStatus()
971    * @since 1.4
972    */
973   public synchronized void setClassAssertionStatus(String name,
974                                                    boolean enabled)
975   {
976     if (classAssertionStatus == null)
977       classAssertionStatus = new HashMap(systemClassAssertionStatus);
978     // The toString() hack catches null, as required.
979     classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled));
980   }
981   
982   /**
983    * Resets the default assertion status of this classloader, its packages
984    * and classes, all to false. This allows overriding defaults inherited
985    * from the command line.
986    *
987    * @see #setDefaultAssertionStatus(boolean)
988    * @see #setClassAssertionStatus(String, boolean)
989    * @see #setPackageAssertionStatus(String, boolean)
990    * @since 1.4
991    */
992   public synchronized void clearAssertionStatus()
993   {
994     defaultAssertionStatus = false;
995     packageAssertionStatus = new HashMap();
996     classAssertionStatus = new HashMap();
997   }
998 }