1 // ClassLoader.java - Define policies for loading Java classes.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
13 import java.io.InputStream;
14 import java.io.IOException;
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;
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
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.
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.
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>).
54 * <p>Users of a <code>ClassLoader</code> will normally just use the methods
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
64 * <p>Subclasses should implement the methods
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>
80 * @author Mark Wielaard
82 * @author Kresten Krab Thorup
85 * @status still missing 1.4 functionality
87 public abstract class ClassLoader
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.
95 final Map loadedClasses = new HashMap();
98 * The desired assertion status of classes loaded by this loader, if not
99 * overridden by package or class instructions.
101 // Package visible for use by Class.
102 boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus();
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.
108 // Package visible for use by Class.
109 static final Map systemPackageAssertionStatus
110 = VMClassLoader.packageAssertionStatus();
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.
118 // Package visible for use by Class.
119 Map packageAssertionStatus;
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.
125 // Package visible for use by Class.
126 static final Map systemClassAssertionStatus
127 = VMClassLoader.classAssertionStatus();
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
135 // Package visible for use by Class.
136 Map classAssertionStatus;
139 * The classloader that is consulted before this classloader.
140 * If null then the parent is the bootstrap classloader.
142 private final ClassLoader parent;
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.
148 private HashMap definedPackages = new HashMap();
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>.
156 * @throws SecurityException if the security check fails
159 public final ClassLoader getParent ()
161 // Check if we may return the parent classloader
162 SecurityManager sm = System.getSecurityManager();
165 Class c = VMSecurityManager.getClassContext()[1];
166 ClassLoader cl = c.getClassLoader();
167 if (cl != null && ! cl.isAncestorOf(this))
168 sm.checkPermission(new RuntimePermission("getClassLoader"));
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.
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).
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.
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
198 public static ClassLoader getSystemClassLoader ()
200 return gnu.gcj.runtime.VMClassLoader.instance;
204 * Creates a <code>ClassLoader</code> with no parent.
205 * @exception java.lang.SecurityException if not allowed
207 protected ClassLoader()
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
219 * @exception java.lang.SecurityException if not allowed
222 protected ClassLoader(ClassLoader parent)
224 SecurityManager security = System.getSecurityManager ();
225 if (security != null)
226 security.checkCreateClassLoader ();
227 this.parent = parent;
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
237 public Class loadClass(String name)
238 throws java.lang.ClassNotFoundException
240 return loadClass (name, false);
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)
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>.
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
260 protected Class loadClass(String name, boolean link)
261 throws java.lang.ClassNotFoundException
263 Class c = findLoadedClass (name);
269 ClassLoader cl = parent;
271 cl = gnu.gcj.runtime.VMClassLoader.instance;
273 c = cl.loadClass (name, link);
275 catch (ClassNotFoundException ex)
277 /* ignore, we'll try findClass */;
282 c = findClass (name);
285 throw new ClassNotFoundException (name);
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.
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>
308 * // Get the bytes that describe the requested class
309 * byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name);
310 * // Get the package name
311 * int lastDot = name.lastIndexOf('.');
314 * String packageName = name.substring(0, lastDot);
315 * // Look if the package already exists
316 * if (getPackage(pkg) == null)
318 * // define the package
319 * definePackage(packageName, ...);
322 * // Define and return the class
323 * return defineClass(name, classBytes, 0, classBytes.length);
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.
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
335 protected Class findClass (String name)
336 throws ClassNotFoundException
338 throw new ClassNotFoundException (name);
341 // Protection Domain definitions
342 // FIXME: should there be a special protection domain used for native code?
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;
354 Permissions permissions = new Permissions();
355 permissions.add(new AllPermission());
356 unknownProtectionDomain = new ProtectionDomain(null, permissions);
358 CodeSource cs = new CodeSource(null, null);
359 defaultProtectionDomain =
360 new ProtectionDomain(cs, Policy.getPolicy().getPermissions(cs));
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
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.
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
383 protected final Class defineClass(byte[] data, int off, int len)
384 throws ClassFormatError
386 return defineClass (null, data, off, len, defaultProtectionDomain);
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>.
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."
408 protected final Class defineClass(String name, byte[] data, int off, int len)
409 throws ClassFormatError
411 return defineClass (name, data, off, len, defaultProtectionDomain);
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.
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.
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
440 protected final synchronized Class defineClass(String name,
444 ProtectionDomain protectionDomain)
445 throws ClassFormatError
447 if (data==null || data.length < off+len || off<0 || len<0)
448 throw new ClassFormatError ("arguments to defineClass "
449 + "are meaningless");
452 if (name != null && findLoadedClass (name) != null)
453 throw new java.lang.LinkageError ("class "
455 + " already loaded");
457 if (protectionDomain == null)
458 protectionDomain = defaultProtectionDomain;
462 Class retval = defineClass0 (name, data, off, len, protectionDomain);
463 loadedClasses.put(retval.getName(), retval);
466 catch (LinkageError x)
470 catch (VirtualMachineError x)
476 // This should never happen, or we are beyond spec.
477 InternalError r = new InternalError ("Unexpected exception "
478 + "while defining class "
485 /** This is the entry point of defineClass into the native code */
486 private native Class defineClass0 (String name,
490 ProtectionDomain protectionDomain)
491 throws ClassFormatError;
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
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''.
507 * For <code>gcj</code>-compiled classes, only the first step is
508 * performed. The compiler will have done the rest already.
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.
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.
518 * @param clazz the class to link.
519 * @exception java.lang.LinkageError
521 protected final void resolveClass(Class clazz)
523 resolveClass0(clazz);
526 static void resolveClass0(Class clazz)
536 markClassErrorState0 (clazz);
539 if (x instanceof LinkageError)
541 else if (x instanceof ClassNotFoundException)
543 e = new NoClassDefFoundError("while resolving class: "
549 e = new LinkageError ("unexpected exception during linking: "
558 /** Internal method. Calls _Jv_PrepareClass and
559 * _Jv_PrepareCompiledClass. This is only called from resolveClass. */
560 private static native void linkClass0(Class clazz);
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);
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
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>).
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
591 * @exception IllegalArgumentException if the package name is null or if
592 * it was already defined by this classloader or one of its parents.
597 protected Package definePackage(String name,
598 String specTitle, String specVendor,
599 String specVersion, String implTitle,
600 String implVendor, String implVersion,
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,
610 synchronized (definedPackages)
612 definedPackages.put(name, p);
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
622 * @param name the package name to find
623 * @return the package, if defined
626 protected Package getPackage(String name)
630 // XXX - Should we use the bootstrap classloader?
633 p = parent.getPackage(name);
637 synchronized (definedPackages)
639 p = (Package) definedPackages.get(name);
647 * Returns all Package objects defined by this classloader and its parents.
649 * @return an array of all defined packages
652 protected Package[] getPackages()
654 Package[] allPackages;
656 // Get all our packages.
658 synchronized(definedPackages)
660 packages = new Package[definedPackages.size()];
661 definedPackages.values().toArray(packages);
664 // If we have a parent get all packages defined by our parents.
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,
675 // XXX - Should we use the bootstrap classloader?
676 allPackages = packages;
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
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()
696 protected String findLibrary(String name)
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.
706 * @param name the class to resolve.
707 * @return the class loaded.
708 * @exception java.lang.LinkageError
709 * @exception java.lang.ClassNotFoundException
711 protected final Class findSystemClass(String name)
712 throws java.lang.ClassNotFoundException
714 return gnu.gcj.runtime.VMClassLoader.instance.loadClass (name);
718 * Helper to set the signers of a class. This should be called after
719 * defining the class.
721 * @param c the Class to set signers of
722 * @param signers the signers to set
725 protected final void setSigners(Class c, Object[] signers)
728 * Does currently nothing. FIXME.
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.
739 protected final synchronized Class findLoadedClass(String name)
741 return (Class) loadedClasses.get(name);
745 * Get a resource using the system classloader.
747 * @param name the name of the resource relative to the system classloader
748 * @return an input stream for the resource, or null
751 public static InputStream getSystemResourceAsStream(String name) {
752 return getSystemClassLoader().getResourceAsStream (name);
756 * Get the URL to a resource using the system classloader.
758 * @param name the name of the resource relative to the system classloader
759 * @return the URL to the resource
762 public static URL getSystemResource(String name) {
763 return getSystemClassLoader().getResource (name);
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.
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
777 public static Enumeration getSystemResources(String name) throws IOException
779 return getSystemClassLoader().getResources(name);
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
792 public InputStream getResourceAsStream(String name)
796 URL res = getResource (name);
799 return res.openStream ();
801 catch (java.io.IOException x)
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)
816 public URL getResource (String name)
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
824 ClassLoader delegate = parent;
826 if (delegate == null)
827 delegate = getSystemClassLoader ();
829 // Protect ourselves from looping.
830 if (this != delegate)
831 result = delegate.getResource (name);
836 return findResource (name);
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.
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.
849 * @param name the name of the resource to be found
850 * @return a URL to the named resource or null when not found
853 protected URL findResource (String name)
855 // Default to returning null. Derived classes implement this.
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.
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.
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
879 public final Enumeration getResources(String name) throws IOException
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
885 Enumeration result = null;
887 ClassLoader delegate = parent;
889 if (delegate == null)
890 delegate = getSystemClassLoader ();
892 // Protect ourselves from looping.
893 if (this != delegate)
894 result = delegate.getResources (name);
899 return findResources (name);
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.
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>.
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
919 protected Enumeration findResources(String name) throws IOException
921 return Collections.enumeration(Collections.EMPTY_LIST);
925 * Set the default assertion status for classes loaded by this classloader,
926 * used unless overridden by a package or class request.
928 * @param enabled true to set the default to enabled
929 * @see #setClassAssertionStatus(String, boolean)
930 * @see #setPackageAssertionStatus(String, boolean)
931 * @see #clearAssertionStatus()
934 public void setDefaultAssertionStatus(boolean enabled)
936 defaultAssertionStatus = enabled;
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.
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()
951 public synchronized void setPackageAssertionStatus(String name,
954 if (packageAssertionStatus == null)
955 packageAssertionStatus
956 = new HashMap(systemPackageAssertionStatus);
957 packageAssertionStatus.put(name, Boolean.valueOf(enabled));
961 * Set the default assertion status for a class. This only affects the
962 * status of top-level classes, any other string is harmless.
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()
972 public synchronized void setClassAssertionStatus(String name,
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));
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.
986 * @see #setDefaultAssertionStatus(boolean)
987 * @see #setClassAssertionStatus(String, boolean)
988 * @see #setPackageAssertionStatus(String, boolean)
991 public synchronized void clearAssertionStatus()
993 defaultAssertionStatus = false;
994 packageAssertionStatus = new HashMap();
995 classAssertionStatus = new HashMap();
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
1003 final boolean isAncestorOf(ClassLoader loader)
1005 while (loader != null)
1009 loader = loader.parent;