OSDN Git Service

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