Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / java / lang / ClassLoader.java
blob9f586c4cffce744bdb29362cded081b1e83a423e
1 /* ClassLoader.java -- responsible for loading classes into the VM
2 Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.lang;
41 import gnu.classpath.SystemProperties;
42 import gnu.classpath.VMStackWalker;
43 import gnu.java.util.DoubleEnumeration;
44 import gnu.java.util.EmptyEnumeration;
46 import java.io.File;
47 import java.io.IOException;
48 import java.io.InputStream;
49 import java.lang.reflect.Constructor;
50 import java.net.URL;
51 import java.net.URLClassLoader;
52 import java.nio.ByteBuffer;
53 import java.security.CodeSource;
54 import java.security.PermissionCollection;
55 import java.security.Policy;
56 import java.security.ProtectionDomain;
57 import java.util.ArrayList;
58 import java.util.Enumeration;
59 import java.util.HashMap;
60 import java.util.Map;
61 import java.util.StringTokenizer;
63 /**
64 * The ClassLoader is a way of customizing the way Java gets its classes
65 * and loads them into memory. The verifier and other standard Java things
66 * still run, but the ClassLoader is allowed great flexibility in determining
67 * where to get the classfiles and when to load and resolve them. For that
68 * matter, a custom ClassLoader can perform on-the-fly code generation or
69 * modification!
71 * <p>Every classloader has a parent classloader that is consulted before
72 * the 'child' classloader when classes or resources should be loaded.
73 * This is done to make sure that classes can be loaded from an hierarchy of
74 * multiple classloaders and classloaders do not accidentially redefine
75 * already loaded classes by classloaders higher in the hierarchy.
77 * <p>The grandparent of all classloaders is the bootstrap classloader, which
78 * loads all the standard system classes as implemented by GNU Classpath. The
79 * other special classloader is the system classloader (also called
80 * application classloader) that loads all classes from the CLASSPATH
81 * (<code>java.class.path</code> system property). The system classloader
82 * is responsible for finding the application classes from the classpath,
83 * and delegates all requests for the standard library classes to its parent
84 * the bootstrap classloader. Most programs will load all their classes
85 * through the system classloaders.
87 * <p>The bootstrap classloader in GNU Classpath is implemented as a couple of
88 * static (native) methods on the package private class
89 * <code>java.lang.VMClassLoader</code>, the system classloader is an
90 * anonymous inner class of ClassLoader and a subclass of
91 * <code>java.net.URLClassLoader</code>.
93 * <p>Users of a <code>ClassLoader</code> will normally just use the methods
94 * <ul>
95 * <li> <code>loadClass()</code> to load a class.</li>
96 * <li> <code>getResource()</code> or <code>getResourceAsStream()</code>
97 * to access a resource.</li>
98 * <li> <code>getResources()</code> to get an Enumeration of URLs to all
99 * the resources provided by the classloader and its parents with the
100 * same name.</li>
101 * </ul>
103 * <p>Subclasses should implement the methods
104 * <ul>
105 * <li> <code>findClass()</code> which is called by <code>loadClass()</code>
106 * when the parent classloader cannot provide a named class.</li>
107 * <li> <code>findResource()</code> which is called by
108 * <code>getResource()</code> when the parent classloader cannot provide
109 * a named resource.</li>
110 * <li> <code>findResources()</code> which is called by
111 * <code>getResource()</code> to combine all the resources with the
112 * same name from the classloader and its parents.</li>
113 * <li> <code>findLibrary()</code> which is called by
114 * <code>Runtime.loadLibrary()</code> when a class defined by the
115 * classloader wants to load a native library.</li>
116 * </ul>
118 * @author John Keiser
119 * @author Mark Wielaard
120 * @author Eric Blake (ebb9@email.byu.edu)
121 * @see Class
122 * @since 1.0
123 * @status still missing 1.4 functionality
125 public abstract class ClassLoader
128 * All packages defined by this classloader. It is not private in order to
129 * allow native code (and trusted subclasses) access to this field.
131 final HashMap definedPackages = new HashMap();
134 * The classloader that is consulted before this classloader.
135 * If null then the parent is the bootstrap classloader.
137 private final ClassLoader parent;
140 * This is true if this classloader was successfully initialized.
141 * This flag is needed to avoid a class loader attack: even if the
142 * security manager rejects an attempt to create a class loader, the
143 * malicious class could have a finalize method which proceeds to
144 * define classes.
146 private final boolean initialized;
148 static class StaticData
151 * The System Class Loader (a.k.a. Application Class Loader). The one
152 * returned by ClassLoader.getSystemClassLoader.
154 static final ClassLoader systemClassLoader =
155 VMClassLoader.getSystemClassLoader();
156 static
158 // Find out if we have to install a default security manager. Note that
159 // this is done here because we potentially need the system class loader
160 // to load the security manager and note also that we don't need the
161 // security manager until the system class loader is created.
162 // If the runtime chooses to use a class loader that doesn't have the
163 // system class loader as its parent, it is responsible for setting
164 // up a security manager before doing so.
165 String secman = SystemProperties.getProperty("java.security.manager");
166 if (secman != null && SecurityManager.current == null)
168 if (secman.equals("") || secman.equals("default"))
170 SecurityManager.current = new SecurityManager();
172 else
176 Class cl = Class.forName(secman, false, StaticData.systemClassLoader);
177 SecurityManager.current = (SecurityManager)cl.newInstance();
179 catch (Exception x)
181 throw (InternalError)
182 new InternalError("Unable to create SecurityManager")
183 .initCause(x);
190 * The default protection domain, used when defining a class with a null
191 * parameter for the domain.
193 static final ProtectionDomain defaultProtectionDomain;
194 static
196 CodeSource cs = new CodeSource(null, null);
197 PermissionCollection perm = Policy.getPolicy().getPermissions(cs);
198 defaultProtectionDomain = new ProtectionDomain(cs, perm);
201 * The command-line state of the package assertion status overrides. This
202 * map is never modified, so it does not need to be synchronized.
204 // Package visible for use by Class.
205 static final Map systemPackageAssertionStatus
206 = VMClassLoader.packageAssertionStatus();
208 * The command-line state of the class assertion status overrides. This
209 * map is never modified, so it does not need to be synchronized.
211 // Package visible for use by Class.
212 static final Map systemClassAssertionStatus
213 = VMClassLoader.classAssertionStatus();
217 * The desired assertion status of classes loaded by this loader, if not
218 * overridden by package or class instructions.
220 // Package visible for use by Class.
221 boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus();
224 * The map of package assertion status overrides, or null if no package
225 * overrides have been specified yet. The values of the map should be
226 * Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented
227 * by the null key. This map must be synchronized on this instance.
229 // Package visible for use by Class.
230 Map packageAssertionStatus;
233 * The map of class assertion status overrides, or null if no class
234 * overrides have been specified yet. The values of the map should be
235 * Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this
236 * instance.
238 // Package visible for use by Class.
239 Map classAssertionStatus;
242 * VM private data.
244 transient Object vmdata;
247 * Create a new ClassLoader with as parent the system classloader. There
248 * may be a security check for <code>checkCreateClassLoader</code>.
250 * @throws SecurityException if the security check fails
252 protected ClassLoader() throws SecurityException
254 this(StaticData.systemClassLoader);
258 * Create a new ClassLoader with the specified parent. The parent will
259 * be consulted when a class or resource is requested through
260 * <code>loadClass()</code> or <code>getResource()</code>. Only when the
261 * parent classloader cannot provide the requested class or resource the
262 * <code>findClass()</code> or <code>findResource()</code> method
263 * of this classloader will be called. There may be a security check for
264 * <code>checkCreateClassLoader</code>.
266 * @param parent the classloader's parent, or null for the bootstrap
267 * classloader
268 * @throws SecurityException if the security check fails
269 * @since 1.2
271 protected ClassLoader(ClassLoader parent)
273 // May we create a new classloader?
274 SecurityManager sm = SecurityManager.current;
275 if (sm != null)
276 sm.checkCreateClassLoader();
277 this.parent = parent;
278 this.initialized = true;
282 * Load a class using this ClassLoader or its parent, without resolving
283 * it. Calls <code>loadClass(name, false)</code>.
285 * <p>Subclasses should not override this method but should override
286 * <code>findClass()</code> which is called by this method.</p>
288 * @param name the name of the class relative to this ClassLoader
289 * @return the loaded class
290 * @throws ClassNotFoundException if the class cannot be found
292 public Class loadClass(String name) throws ClassNotFoundException
294 return loadClass(name, false);
298 * Load a class using this ClassLoader or its parent, possibly resolving
299 * it as well using <code>resolveClass()</code>. It first tries to find
300 * out if the class has already been loaded through this classloader by
301 * calling <code>findLoadedClass()</code>. Then it calls
302 * <code>loadClass()</code> on the parent classloader (or when there is
303 * no parent it uses the VM bootclassloader). If the class is still
304 * not loaded it tries to create a new class by calling
305 * <code>findClass()</code>. Finally when <code>resolve</code> is
306 * <code>true</code> it also calls <code>resolveClass()</code> on the
307 * newly loaded class.
309 * <p>Subclasses should not override this method but should override
310 * <code>findClass()</code> which is called by this method.</p>
312 * @param name the fully qualified name of the class to load
313 * @param resolve whether or not to resolve the class
314 * @return the loaded class
315 * @throws ClassNotFoundException if the class cannot be found
317 protected synchronized Class loadClass(String name, boolean resolve)
318 throws ClassNotFoundException
320 // Have we already loaded this class?
321 Class c = findLoadedClass(name);
322 if (c == null)
324 // Can the class be loaded by a parent?
327 if (parent == null)
329 c = VMClassLoader.loadClass(name, resolve);
330 if (c != null)
331 return c;
333 else
335 return parent.loadClass(name, resolve);
338 catch (ClassNotFoundException e)
341 // Still not found, we have to do it ourself.
342 c = findClass(name);
344 if (resolve)
345 resolveClass(c);
346 return c;
350 * Called for every class name that is needed but has not yet been
351 * defined by this classloader or one of its parents. It is called by
352 * <code>loadClass()</code> after both <code>findLoadedClass()</code> and
353 * <code>parent.loadClass()</code> couldn't provide the requested class.
355 * <p>The default implementation throws a
356 * <code>ClassNotFoundException</code>. Subclasses should override this
357 * method. An implementation of this method in a subclass should get the
358 * class bytes of the class (if it can find them), if the package of the
359 * requested class doesn't exist it should define the package and finally
360 * it should call define the actual class. It does not have to resolve the
361 * class. It should look something like the following:<br>
363 * <pre>
364 * // Get the bytes that describe the requested class
365 * byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name);
366 * // Get the package name
367 * int lastDot = name.lastIndexOf('.');
368 * if (lastDot != -1)
370 * String packageName = name.substring(0, lastDot);
371 * // Look if the package already exists
372 * if (getPackage(packageName) == null)
374 * // define the package
375 * definePackage(packageName, ...);
378 * // Define and return the class
379 * return defineClass(name, classBytes, 0, classBytes.length);
380 * </pre>
382 * <p><code>loadClass()</code> makes sure that the <code>Class</code>
383 * returned by <code>findClass()</code> will later be returned by
384 * <code>findLoadedClass()</code> when the same class name is requested.
386 * @param name class name to find (including the package name)
387 * @return the requested Class
388 * @throws ClassNotFoundException when the class can not be found
389 * @since 1.2
391 protected Class findClass(String name) throws ClassNotFoundException
393 throw new ClassNotFoundException(name);
397 * Helper to define a class using a string of bytes. This version is not
398 * secure.
400 * @param data the data representing the classfile, in classfile format
401 * @param offset the offset into the data where the classfile starts
402 * @param len the length of the classfile data in the array
403 * @return the class that was defined
404 * @throws ClassFormatError if data is not in proper classfile format
405 * @throws IndexOutOfBoundsException if offset or len is negative, or
406 * offset + len exceeds data
407 * @deprecated use {@link #defineClass(String, byte[], int, int)} instead
409 protected final Class defineClass(byte[] data, int offset, int len)
410 throws ClassFormatError
412 return defineClass(null, data, offset, len);
416 * Helper to define a class using a string of bytes without a
417 * ProtectionDomain. Subclasses should call this method from their
418 * <code>findClass()</code> implementation. The name should use '.'
419 * separators, and discard the trailing ".class". The default protection
420 * domain has the permissions of
421 * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>.
423 * @param name the name to give the class, or null if unknown
424 * @param data the data representing the classfile, in classfile format
425 * @param offset the offset into the data where the classfile starts
426 * @param len the length of the classfile data in the array
427 * @return the class that was defined
428 * @throws ClassFormatError if data is not in proper classfile format
429 * @throws IndexOutOfBoundsException if offset or len is negative, or
430 * offset + len exceeds data
431 * @throws SecurityException if name starts with "java."
432 * @since 1.1
434 protected final Class defineClass(String name, byte[] data, int offset,
435 int len) throws ClassFormatError
437 return defineClass(name, data, offset, len, null);
441 * Helper to define a class using a string of bytes. Subclasses should call
442 * this method from their <code>findClass()</code> implementation. If the
443 * domain is null, the default of
444 * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>
445 * is used. Once a class has been defined in a package, all further classes
446 * in that package must have the same set of certificates or a
447 * SecurityException is thrown.
449 * @param name the name to give the class. null if unknown
450 * @param data the data representing the classfile, in classfile format
451 * @param offset the offset into the data where the classfile starts
452 * @param len the length of the classfile data in the array
453 * @param domain the ProtectionDomain to give to the class, null for the
454 * default protection domain
455 * @return the class that was defined
456 * @throws ClassFormatError if data is not in proper classfile format
457 * @throws IndexOutOfBoundsException if offset or len is negative, or
458 * offset + len exceeds data
459 * @throws SecurityException if name starts with "java.", or if certificates
460 * do not match up
461 * @since 1.2
463 protected final synchronized Class defineClass(String name, byte[] data,
464 int offset, int len,
465 ProtectionDomain domain)
466 throws ClassFormatError
468 checkInitialized();
469 if (domain == null)
470 domain = StaticData.defaultProtectionDomain;
472 return VMClassLoader.defineClass(this, name, data, offset, len, domain);
476 * Helper to define a class using the contents of a byte buffer. If
477 * the domain is null, the default of
478 * <code>Policy.getPolicy().getPermissions(new CodeSource(null,
479 * null))</code> is used. Once a class has been defined in a
480 * package, all further classes in that package must have the same
481 * set of certificates or a SecurityException is thrown.
483 * @param name the name to give the class. null if unknown
484 * @param buf a byte buffer containing bytes that form a class.
485 * @param domain the ProtectionDomain to give to the class, null for the
486 * default protection domain
487 * @return the class that was defined
488 * @throws ClassFormatError if data is not in proper classfile format
489 * @throws NoClassDefFoundError if the supplied name is not the same as
490 * the one specified by the byte buffer.
491 * @throws SecurityException if name starts with "java.", or if certificates
492 * do not match up
493 * @since 1.5
495 protected final Class defineClass(String name, ByteBuffer buf,
496 ProtectionDomain domain)
497 throws ClassFormatError
499 byte[] data = new byte[buf.remaining()];
500 buf.get(data);
501 return defineClass(name, data, 0, data.length, domain);
505 * Links the class, if that has not already been done. Linking basically
506 * resolves all references to other classes made by this class.
508 * @param c the class to resolve
509 * @throws NullPointerException if c is null
510 * @throws LinkageError if linking fails
512 protected final void resolveClass(Class c)
514 checkInitialized();
515 VMClassLoader.resolveClass(c);
519 * Helper to find a Class using the system classloader, possibly loading it.
520 * A subclass usually does not need to call this, if it correctly
521 * overrides <code>findClass(String)</code>.
523 * @param name the name of the class to find
524 * @return the found class
525 * @throws ClassNotFoundException if the class cannot be found
527 protected final Class findSystemClass(String name)
528 throws ClassNotFoundException
530 checkInitialized();
531 return Class.forName(name, false, StaticData.systemClassLoader);
535 * Returns the parent of this classloader. If the parent of this
536 * classloader is the bootstrap classloader then this method returns
537 * <code>null</code>. A security check may be performed on
538 * <code>RuntimePermission("getClassLoader")</code>.
540 * @return the parent <code>ClassLoader</code>
541 * @throws SecurityException if the security check fails
542 * @since 1.2
544 public final ClassLoader getParent()
546 // Check if we may return the parent classloader.
547 SecurityManager sm = SecurityManager.current;
548 if (sm != null)
550 ClassLoader cl = VMStackWalker.getCallingClassLoader();
551 if (cl != null && ! cl.isAncestorOf(this))
552 sm.checkPermission(new RuntimePermission("getClassLoader"));
554 return parent;
558 * Helper to set the signers of a class. This should be called after
559 * defining the class.
561 * @param c the Class to set signers of
562 * @param signers the signers to set
563 * @since 1.1
565 protected final void setSigners(Class c, Object[] signers)
567 checkInitialized();
568 c.setSigners(signers);
572 * Helper to find an already-loaded class in this ClassLoader.
574 * @param name the name of the class to find
575 * @return the found Class, or null if it is not found
576 * @since 1.1
578 protected final synchronized Class findLoadedClass(String name)
580 checkInitialized();
581 return VMClassLoader.findLoadedClass(this, name);
585 * Get the URL to a resource using this classloader or one of its parents.
586 * First tries to get the resource by calling <code>getResource()</code>
587 * on the parent classloader. If the parent classloader returns null then
588 * it tries finding the resource by calling <code>findResource()</code> on
589 * this classloader. The resource name should be separated by '/' for path
590 * elements.
592 * <p>Subclasses should not override this method but should override
593 * <code>findResource()</code> which is called by this method.
595 * @param name the name of the resource relative to this classloader
596 * @return the URL to the resource or null when not found
598 public URL getResource(String name)
600 URL result;
602 if (parent == null)
603 result = VMClassLoader.getResource(name);
604 else
605 result = parent.getResource(name);
607 if (result == null)
608 result = findResource(name);
609 return result;
613 * Returns an Enumeration of all resources with a given name that can
614 * be found by this classloader and its parents. Certain classloaders
615 * (such as the URLClassLoader when given multiple jar files) can have
616 * multiple resources with the same name that come from multiple locations.
617 * It can also occur that a parent classloader offers a resource with a
618 * certain name and the child classloader also offers a resource with that
619 * same name. <code>getResource()</code> only offers the first resource (of the
620 * parent) with a given name. This method lists all resources with the
621 * same name. The name should use '/' as path separators.
623 * <p>The Enumeration is created by first calling <code>getResources()</code>
624 * on the parent classloader and then calling <code>findResources()</code>
625 * on this classloader.</p>
627 * @param name the resource name
628 * @return an enumaration of all resources found
629 * @throws IOException if I/O errors occur in the process
630 * @since 1.2
632 public final Enumeration getResources(String name) throws IOException
634 Enumeration parentResources;
635 if (parent == null)
636 parentResources = VMClassLoader.getResources(name);
637 else
638 parentResources = parent.getResources(name);
639 return new DoubleEnumeration(parentResources, findResources(name));
643 * Called whenever all locations of a named resource are needed.
644 * It is called by <code>getResources()</code> after it has called
645 * <code>parent.getResources()</code>. The results are combined by
646 * the <code>getResources()</code> method.
648 * <p>The default implementation always returns an empty Enumeration.
649 * Subclasses should override it when they can provide an Enumeration of
650 * URLs (possibly just one element) to the named resource.
651 * The first URL of the Enumeration should be the same as the one
652 * returned by <code>findResource</code>.
654 * @param name the name of the resource to be found
655 * @return a possibly empty Enumeration of URLs to the named resource
656 * @throws IOException if I/O errors occur in the process
657 * @since 1.2
659 protected Enumeration findResources(String name) throws IOException
661 return EmptyEnumeration.getInstance();
665 * Called whenever a resource is needed that could not be provided by
666 * one of the parents of this classloader. It is called by
667 * <code>getResource()</code> after <code>parent.getResource()</code>
668 * couldn't provide the requested resource.
670 * <p>The default implementation always returns null. Subclasses should
671 * override this method when they can provide a way to return a URL
672 * to a named resource.
674 * @param name the name of the resource to be found
675 * @return a URL to the named resource or null when not found
676 * @since 1.2
678 protected URL findResource(String name)
680 return null;
684 * Get the URL to a resource using the system classloader.
686 * @param name the name of the resource relative to the system classloader
687 * @return the URL to the resource
688 * @since 1.1
690 public static final URL getSystemResource(String name)
692 return StaticData.systemClassLoader.getResource(name);
696 * Get an Enumeration of URLs to resources with a given name using the
697 * the system classloader. The enumeration firsts lists the resources with
698 * the given name that can be found by the bootstrap classloader followed
699 * by the resources with the given name that can be found on the classpath.
701 * @param name the name of the resource relative to the system classloader
702 * @return an Enumeration of URLs to the resources
703 * @throws IOException if I/O errors occur in the process
704 * @since 1.2
706 public static Enumeration getSystemResources(String name) throws IOException
708 return StaticData.systemClassLoader.getResources(name);
712 * Get a resource as stream using this classloader or one of its parents.
713 * First calls <code>getResource()</code> and if that returns a URL to
714 * the resource then it calls and returns the InputStream given by
715 * <code>URL.openStream()</code>.
717 * <p>Subclasses should not override this method but should override
718 * <code>findResource()</code> which is called by this method.
720 * @param name the name of the resource relative to this classloader
721 * @return an InputStream to the resource, or null
722 * @since 1.1
724 public InputStream getResourceAsStream(String name)
728 URL url = getResource(name);
729 if (url == null)
730 return null;
731 return url.openStream();
733 catch (IOException e)
735 return null;
740 * Get a resource using the system classloader.
742 * @param name the name of the resource relative to the system classloader
743 * @return an input stream for the resource, or null
744 * @since 1.1
746 public static final InputStream getSystemResourceAsStream(String name)
750 URL url = getSystemResource(name);
751 if (url == null)
752 return null;
753 return url.openStream();
755 catch (IOException e)
757 return null;
762 * Returns the system classloader. The system classloader (also called
763 * the application classloader) is the classloader that is used to
764 * load the application classes on the classpath (given by the system
765 * property <code>java.class.path</code>. This is set as the context
766 * class loader for a thread. The system property
767 * <code>java.system.class.loader</code>, if defined, is taken to be the
768 * name of the class to use as the system class loader, which must have
769 * a public constructor which takes a ClassLoader as a parent. The parent
770 * class loader passed in the constructor is the default system class
771 * loader.
773 * <p>Note that this is different from the bootstrap classloader that
774 * actually loads all the real "system" classes.
776 * <p>A security check will be performed for
777 * <code>RuntimePermission("getClassLoader")</code> if the calling class
778 * is not a parent of the system class loader.
780 * @return the system class loader
781 * @throws SecurityException if the security check fails
782 * @throws IllegalStateException if this is called recursively
783 * @throws Error if <code>java.system.class.loader</code> fails to load
784 * @since 1.2
786 public static ClassLoader getSystemClassLoader()
788 // Check if we may return the system classloader
789 SecurityManager sm = SecurityManager.current;
790 if (sm != null)
792 ClassLoader cl = VMStackWalker.getCallingClassLoader();
793 if (cl != null && cl != StaticData.systemClassLoader)
794 sm.checkPermission(new RuntimePermission("getClassLoader"));
797 return StaticData.systemClassLoader;
801 * Defines a new package and creates a Package object. The package should
802 * be defined before any class in the package is defined with
803 * <code>defineClass()</code>. The package should not yet be defined
804 * before in this classloader or in one of its parents (which means that
805 * <code>getPackage()</code> should return <code>null</code>). All
806 * parameters except the <code>name</code> of the package may be
807 * <code>null</code>.
809 * <p>Subclasses should call this method from their <code>findClass()</code>
810 * implementation before calling <code>defineClass()</code> on a Class
811 * in a not yet defined Package (which can be checked by calling
812 * <code>getPackage()</code>).
814 * @param name the name of the Package
815 * @param specTitle the name of the specification
816 * @param specVendor the name of the specification designer
817 * @param specVersion the version of this specification
818 * @param implTitle the name of the implementation
819 * @param implVendor the vendor that wrote this implementation
820 * @param implVersion the version of this implementation
821 * @param sealed if sealed the origin of the package classes
822 * @return the Package object for the specified package
823 * @throws IllegalArgumentException if the package name is null or it
824 * was already defined by this classloader or one of its parents
825 * @see Package
826 * @since 1.2
828 protected Package definePackage(String name, String specTitle,
829 String specVendor, String specVersion,
830 String implTitle, String implVendor,
831 String implVersion, URL sealed)
833 if (getPackage(name) != null)
834 throw new IllegalArgumentException("Package " + name
835 + " already defined");
836 Package p = new Package(name, specTitle, specVendor, specVersion,
837 implTitle, implVendor, implVersion, sealed);
838 synchronized (definedPackages)
840 definedPackages.put(name, p);
842 return p;
846 * Returns the Package object for the requested package name. It returns
847 * null when the package is not defined by this classloader or one of its
848 * parents.
850 * @param name the package name to find
851 * @return the package, if defined
852 * @since 1.2
854 protected Package getPackage(String name)
856 Package p;
857 if (parent == null)
858 p = VMClassLoader.getPackage(name);
859 else
860 p = parent.getPackage(name);
862 if (p == null)
864 synchronized (definedPackages)
866 p = (Package) definedPackages.get(name);
869 return p;
873 * Returns all Package objects defined by this classloader and its parents.
875 * @return an array of all defined packages
876 * @since 1.2
878 protected Package[] getPackages()
880 // Get all our packages.
881 Package[] packages;
882 synchronized(definedPackages)
884 packages = new Package[definedPackages.size()];
885 definedPackages.values().toArray(packages);
888 // If we have a parent get all packages defined by our parents.
889 Package[] parentPackages;
890 if (parent == null)
891 parentPackages = VMClassLoader.getPackages();
892 else
893 parentPackages = parent.getPackages();
895 Package[] allPackages = new Package[parentPackages.length
896 + packages.length];
897 System.arraycopy(parentPackages, 0, allPackages, 0,
898 parentPackages.length);
899 System.arraycopy(packages, 0, allPackages, parentPackages.length,
900 packages.length);
901 return allPackages;
905 * Called by <code>Runtime.loadLibrary()</code> to get an absolute path
906 * to a (system specific) library that was requested by a class loaded
907 * by this classloader. The default implementation returns
908 * <code>null</code>. It should be implemented by subclasses when they
909 * have a way to find the absolute path to a library. If this method
910 * returns null the library is searched for in the default locations
911 * (the directories listed in the <code>java.library.path</code> system
912 * property).
914 * @param name the (system specific) name of the requested library
915 * @return the full pathname to the requested library, or null
916 * @see Runtime#loadLibrary(String)
917 * @since 1.2
919 protected String findLibrary(String name)
921 return null;
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()
932 * @since 1.4
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(boolean)
947 * @see #setClassAssertionStatus(String, boolean)
948 * @see #clearAssertionStatus()
949 * @since 1.4
951 public synchronized void setPackageAssertionStatus(String name,
952 boolean enabled)
954 if (packageAssertionStatus == null)
955 packageAssertionStatus
956 = new HashMap(StaticData.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(boolean)
968 * @see #setPackageAssertionStatus(String, boolean)
969 * @see #clearAssertionStatus()
970 * @since 1.4
972 public synchronized void setClassAssertionStatus(String name,
973 boolean enabled)
975 if (classAssertionStatus == null)
976 classAssertionStatus =
977 new HashMap(StaticData.systemClassAssertionStatus);
978 // The toString() hack catches null, as required.
979 classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled));
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.
987 * @see #setDefaultAssertionStatus(boolean)
988 * @see #setClassAssertionStatus(String, boolean)
989 * @see #setPackageAssertionStatus(String, boolean)
990 * @since 1.4
992 public synchronized void clearAssertionStatus()
994 defaultAssertionStatus = false;
995 packageAssertionStatus = new HashMap();
996 classAssertionStatus = new HashMap();
1000 * Return true if this loader is either the specified class loader
1001 * or an ancestor thereof.
1002 * @param loader the class loader to check
1004 final boolean isAncestorOf(ClassLoader loader)
1006 while (loader != null)
1008 if (this == loader)
1009 return true;
1010 loader = loader.parent;
1012 return false;
1015 private static URL[] getExtClassLoaderUrls()
1017 String classpath = SystemProperties.getProperty("java.ext.dirs", "");
1018 StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator);
1019 ArrayList list = new ArrayList();
1020 while (tok.hasMoreTokens())
1024 File f = new File(tok.nextToken());
1025 File[] files = f.listFiles();
1026 if (files != null)
1027 for (int i = 0; i < files.length; i++)
1028 list.add(files[i].toURL());
1030 catch(Exception x)
1034 URL[] urls = new URL[list.size()];
1035 list.toArray(urls);
1036 return urls;
1039 private static void addFileURL(ArrayList list, String file)
1043 list.add(new File(file).toURL());
1045 catch(java.net.MalformedURLException x)
1050 private static URL[] getSystemClassLoaderUrls()
1052 String classpath = SystemProperties.getProperty("java.class.path", ".");
1053 StringTokenizer tok = new StringTokenizer(classpath, File.pathSeparator, true);
1054 ArrayList list = new ArrayList();
1055 while (tok.hasMoreTokens())
1057 String s = tok.nextToken();
1058 if (s.equals(File.pathSeparator))
1059 addFileURL(list, ".");
1060 else
1062 addFileURL(list, s);
1063 if (tok.hasMoreTokens())
1065 // Skip the separator.
1066 tok.nextToken();
1067 // If the classpath ended with a separator,
1068 // append the current directory.
1069 if (!tok.hasMoreTokens())
1070 addFileURL(list, ".");
1074 URL[] urls = new URL[list.size()];
1075 list.toArray(urls);
1076 return urls;
1079 static ClassLoader defaultGetSystemClassLoader()
1081 return createAuxiliarySystemClassLoader(
1082 createSystemClassLoader(getSystemClassLoaderUrls(),
1083 createExtClassLoader(getExtClassLoaderUrls(), null)));
1086 static ClassLoader createExtClassLoader(URL[] urls, ClassLoader parent)
1088 if (urls.length > 0)
1089 return new URLClassLoader(urls, parent);
1090 else
1091 return parent;
1094 static ClassLoader createSystemClassLoader(URL[] urls, ClassLoader parent)
1096 return
1097 new URLClassLoader(urls, parent)
1099 protected synchronized Class loadClass(String name,
1100 boolean resolve)
1101 throws ClassNotFoundException
1103 SecurityManager sm = SecurityManager.current;
1104 if (sm != null)
1106 int lastDot = name.lastIndexOf('.');
1107 if (lastDot != -1)
1108 sm.checkPackageAccess(name.substring(0, lastDot));
1110 return super.loadClass(name, resolve);
1115 static ClassLoader createAuxiliarySystemClassLoader(ClassLoader parent)
1117 String loader = SystemProperties.getProperty("java.system.class.loader", null);
1118 if (loader == null)
1120 return parent;
1124 Constructor c = Class.forName(loader, false, parent)
1125 .getConstructor(new Class[] { ClassLoader.class });
1126 return (ClassLoader)c.newInstance(new Object[] { parent });
1128 catch (Exception e)
1130 System.err.println("Requested system classloader " + loader + " failed.");
1131 throw (Error)
1132 new Error("Requested system classloader " + loader + " failed.")
1133 .initCause(e);
1138 * Before doing anything "dangerous" please call this method to make sure
1139 * this class loader instance was properly constructed (and not obtained
1140 * by exploiting the finalizer attack)
1141 * @see #initialized
1143 private void checkInitialized()
1145 if (! initialized)
1146 throw new SecurityException("attempt to use uninitialized class loader");