2 * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
27 import java.io.InputStream;
28 import java.io.IOException;
30 import java.util.Enumeration;
31 import java.util.NoSuchElementException;
32 import org.apidesign.bck2brwsr.core.JavaScriptBody;
35 * A class loader is an object that is responsible for loading classes. The
36 * class <tt>ClassLoader</tt> is an abstract class. Given the <a
37 * href="#name">binary name</a> of a class, a class loader should attempt to
38 * locate or generate data that constitutes a definition for the class. A
39 * typical strategy is to transform the name into a file name and then read a
40 * "class file" of that name from a file system.
42 * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
43 * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
46 * <p> <tt>Class</tt> objects for array classes are not created by class
47 * loaders, but are created automatically as required by the Java runtime.
48 * The class loader for an array class, as returned by {@link
49 * Class#getClassLoader()} is the same as the class loader for its element
50 * type; if the element type is a primitive type, then the array class has no
53 * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
54 * extend the manner in which the Java virtual machine dynamically loads
57 * <p> Class loaders may typically be used by security managers to indicate
60 * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
61 * classes and resources. Each instance of <tt>ClassLoader</tt> has an
62 * associated parent class loader. When requested to find a class or
63 * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
64 * class or resource to its parent class loader before attempting to find the
65 * class or resource itself. The virtual machine's built-in class loader,
66 * called the "bootstrap class loader", does not itself have a parent but may
67 * serve as the parent of a <tt>ClassLoader</tt> instance.
69 * <p> Class loaders that support concurrent loading of classes are known as
70 * <em>parallel capable</em> class loaders and are required to register
71 * themselves at their class initialization time by invoking the
73 * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
74 * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
75 * capable by default. However, its subclasses still need to register themselves
76 * if they are parallel capable. <br>
77 * In environments in which the delegation model is not strictly
78 * hierarchical, class loaders need to be parallel capable, otherwise class
79 * loading can lead to deadlocks because the loader lock is held for the
80 * duration of the class loading process (see {@link #loadClass
81 * <tt>loadClass</tt>} methods).
83 * <p> Normally, the Java virtual machine loads classes from the local file
84 * system in a platform-dependent manner. For example, on UNIX systems, the
85 * virtual machine loads classes from the directory defined by the
86 * <tt>CLASSPATH</tt> environment variable.
88 * <p> However, some classes may not originate from a file; they may originate
89 * from other sources, such as the network, or they could be constructed by an
90 * application. The method {@link #defineClass(String, byte[], int, int)
91 * <tt>defineClass</tt>} converts an array of bytes into an instance of class
92 * <tt>Class</tt>. Instances of this newly defined class can be created using
93 * {@link Class#newInstance <tt>Class.newInstance</tt>}.
95 * <p> The methods and constructors of objects created by a class loader may
96 * reference other classes. To determine the class(es) referred to, the Java
97 * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
98 * the class loader that originally created the class.
100 * <p> For example, an application could create a network class loader to
101 * download class files from a server. Sample code might look like:
104 * ClassLoader loader = new NetworkClassLoader(host, port);
105 * Object main = loader.loadClass("Main", true).newInstance();
106 * . . .
107 * </pre></blockquote>
109 * <p> The network class loader subclass must define the methods {@link
110 * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
111 * from the network. Once it has downloaded the bytes that make up the class,
112 * it should use the method {@link #defineClass <tt>defineClass</tt>} to
113 * create a class instance. A sample implementation is:
116 * class NetworkClassLoader extends ClassLoader {
120 * public Class findClass(String name) {
121 * byte[] b = loadClassData(name);
122 * return defineClass(name, b, 0, b.length);
125 * private byte[] loadClassData(String name) {
126 * // load the class data from the connection
127 * . . .
130 * </pre></blockquote>
132 * <h4> <a name="name">Binary names</a> </h4>
134 * <p> Any class name provided as a {@link String} parameter to methods in
135 * <tt>ClassLoader</tt> must be a binary name as defined by
136 * <cite>The Java™ Language Specification</cite>.
138 * <p> Examples of valid class names include:
141 * "javax.swing.JSpinner$DefaultEditor"
142 * "java.security.KeyStore$Builder$FileBuilder$1"
143 * "java.net.URLClassLoader$3$1"
144 * </pre></blockquote>
146 * @see #resolveClass(Class)
149 public abstract class ClassLoader {
151 @JavaScriptBody(args = {}, body = "")
152 private static native void registerNatives();
157 // The parent class loader for delegation
158 // Note: VM hardcoded the offset of this field, thus all new fields
159 // must be added *after* it.
160 private final ClassLoader parent;
164 * Creates a new class loader using the specified parent class loader for
167 * <p> If there is a security manager, its {@link
168 * SecurityManager#checkCreateClassLoader()
169 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
170 * a security exception. </p>
173 * The parent class loader
175 * @throws SecurityException
176 * If a security manager exists and its
177 * <tt>checkCreateClassLoader</tt> method doesn't allow creation
178 * of a new class loader.
182 protected ClassLoader(ClassLoader parent) {
183 this.parent = parent;
187 * Creates a new class loader using the <tt>ClassLoader</tt> returned by
188 * the method {@link #getSystemClassLoader()
189 * <tt>getSystemClassLoader()</tt>} as the parent class loader.
191 * <p> If there is a security manager, its {@link
192 * SecurityManager#checkCreateClassLoader()
193 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
194 * a security exception. </p>
196 * @throws SecurityException
197 * If a security manager exists and its
198 * <tt>checkCreateClassLoader</tt> method doesn't allow creation
199 * of a new class loader.
201 protected ClassLoader() {
208 * Loads the class with the specified <a href="#name">binary name</a>.
209 * This method searches for classes in the same manner as the {@link
210 * #loadClass(String, boolean)} method. It is invoked by the Java virtual
211 * machine to resolve class references. Invoking this method is equivalent
212 * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
216 * The <a href="#name">binary name</a> of the class
218 * @return The resulting <tt>Class</tt> object
220 * @throws ClassNotFoundException
221 * If the class was not found
223 public Class<?> loadClass(String name) throws ClassNotFoundException {
224 return loadClass(name, false);
228 * Loads the class with the specified <a href="#name">binary name</a>. The
229 * default implementation of this method searches for classes in the
234 * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
235 * has already been loaded. </p></li>
237 * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
238 * on the parent class loader. If the parent is <tt>null</tt> the class
239 * loader built-in to the virtual machine is used, instead. </p></li>
241 * <li><p> Invoke the {@link #findClass(String)} method to find the
246 * <p> If the class was found using the above steps, and the
247 * <tt>resolve</tt> flag is true, this method will then invoke the {@link
248 * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
250 * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
251 * #findClass(String)}, rather than this method. </p>
253 * <p> Unless overridden, this method synchronizes on the result of
254 * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
255 * during the entire class loading process.
258 * The <a href="#name">binary name</a> of the class
261 * If <tt>true</tt> then resolve the class
263 * @return The resulting <tt>Class</tt> object
265 * @throws ClassNotFoundException
266 * If the class could not be found
268 protected Class<?> loadClass(String name, boolean resolve)
269 throws ClassNotFoundException
271 synchronized (getClassLoadingLock(name)) {
272 // First, check if the class has already been loaded
273 Class c = findLoadedClass(name);
276 if (parent != null) {
277 c = parent.loadClass(name, false);
279 c = findBootstrapClassOrNull(name);
281 } catch (ClassNotFoundException e) {
282 // ClassNotFoundException thrown if class not found
283 // from the non-null parent class loader
287 // If still not found, then invoke findClass in order
288 // to find the class.
291 // // this is the defining class loader; record the stats
292 // sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
293 // sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
294 // sun.misc.PerfCounter.getFindClasses().increment();
305 * Returns the lock object for class loading operations.
306 * For backward compatibility, the default implementation of this method
307 * behaves as follows. If this ClassLoader object is registered as
308 * parallel capable, the method returns a dedicated object associated
309 * with the specified class name. Otherwise, the method returns this
310 * ClassLoader object. </p>
313 * The name of the to-be-loaded class
315 * @return the lock for class loading operations
317 * @throws NullPointerException
318 * If registered as parallel capable and <tt>className</tt> is null
320 * @see #loadClass(String, boolean)
324 protected Object getClassLoadingLock(String className) {
330 * Finds the class with the specified <a href="#name">binary name</a>.
331 * This method should be overridden by class loader implementations that
332 * follow the delegation model for loading classes, and will be invoked by
333 * the {@link #loadClass <tt>loadClass</tt>} method after checking the
334 * parent class loader for the requested class. The default implementation
335 * throws a <tt>ClassNotFoundException</tt>. </p>
338 * The <a href="#name">binary name</a> of the class
340 * @return The resulting <tt>Class</tt> object
342 * @throws ClassNotFoundException
343 * If the class could not be found
347 protected Class<?> findClass(String name) throws ClassNotFoundException {
348 throw new ClassNotFoundException(name);
352 * Converts an array of bytes into an instance of class <tt>Class</tt>.
353 * Before the <tt>Class</tt> can be used it must be resolved. This method
354 * is deprecated in favor of the version that takes a <a
355 * href="#name">binary name</a> as its first argument, and is more secure.
358 * The bytes that make up the class data. The bytes in positions
359 * <tt>off</tt> through <tt>off+len-1</tt> should have the format
360 * of a valid class file as defined by
361 * <cite>The Java™ Virtual Machine Specification</cite>.
364 * The start offset in <tt>b</tt> of the class data
367 * The length of the class data
369 * @return The <tt>Class</tt> object that was created from the specified
372 * @throws ClassFormatError
373 * If the data did not contain a valid class
375 * @throws IndexOutOfBoundsException
376 * If either <tt>off</tt> or <tt>len</tt> is negative, or if
377 * <tt>off+len</tt> is greater than <tt>b.length</tt>.
379 * @throws SecurityException
380 * If an attempt is made to add this class to a package that
381 * contains classes that were signed by a different set of
382 * certificates than this class, or if an attempt is made
383 * to define a class in a package with a fully-qualified name
384 * that starts with "{@code java.}".
386 * @see #loadClass(String, boolean)
387 * @see #resolveClass(Class)
389 * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
390 * defineClass(String, byte[], int, int)}
393 protected final Class<?> defineClass(byte[] b, int off, int len)
394 throws ClassFormatError
396 throw new SecurityException();
400 * Converts an array of bytes into an instance of class <tt>Class</tt>.
401 * Before the <tt>Class</tt> can be used it must be resolved.
403 * <p> This method assigns a default {@link java.security.ProtectionDomain
404 * <tt>ProtectionDomain</tt>} to the newly defined class. The
405 * <tt>ProtectionDomain</tt> is effectively granted the same set of
406 * permissions returned when {@link
407 * java.security.Policy#getPermissions(java.security.CodeSource)
408 * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
409 * is invoked. The default domain is created on the first invocation of
410 * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
411 * and re-used on subsequent invocations.
413 * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
414 * the {@link #defineClass(String, byte[], int, int,
415 * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
416 * <tt>ProtectionDomain</tt> as one of its arguments. </p>
419 * The expected <a href="#name">binary name</a> of the class, or
420 * <tt>null</tt> if not known
423 * The bytes that make up the class data. The bytes in positions
424 * <tt>off</tt> through <tt>off+len-1</tt> should have the format
425 * of a valid class file as defined by
426 * <cite>The Java™ Virtual Machine Specification</cite>.
429 * The start offset in <tt>b</tt> of the class data
432 * The length of the class data
434 * @return The <tt>Class</tt> object that was created from the specified
437 * @throws ClassFormatError
438 * If the data did not contain a valid class
440 * @throws IndexOutOfBoundsException
441 * If either <tt>off</tt> or <tt>len</tt> is negative, or if
442 * <tt>off+len</tt> is greater than <tt>b.length</tt>.
444 * @throws SecurityException
445 * If an attempt is made to add this class to a package that
446 * contains classes that were signed by a different set of
447 * certificates than this class (which is unsigned), or if
448 * <tt>name</tt> begins with "<tt>java.</tt>".
450 * @see #loadClass(String, boolean)
451 * @see #resolveClass(Class)
452 * @see java.security.CodeSource
453 * @see java.security.SecureClassLoader
457 protected final Class<?> defineClass(String name, byte[] b, int off, int len)
458 throws ClassFormatError
460 throw new SecurityException();
464 * Links the specified class. This (misleadingly named) method may be
465 * used by a class loader to link a class. If the class <tt>c</tt> has
466 * already been linked, then this method simply returns. Otherwise, the
467 * class is linked as described in the "Execution" chapter of
468 * <cite>The Java™ Language Specification</cite>.
474 * @throws NullPointerException
475 * If <tt>c</tt> is <tt>null</tt>.
477 * @see #defineClass(String, byte[], int, int)
479 protected final void resolveClass(Class<?> c) {
483 private native void resolveClass0(Class c);
487 * Returns the class with the given <a href="#name">binary name</a> if this
488 * loader has been recorded by the Java virtual machine as an initiating
489 * loader of a class with that <a href="#name">binary name</a>. Otherwise
490 * <tt>null</tt> is returned. </p>
493 * The <a href="#name">binary name</a> of the class
495 * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
500 protected final Class<?> findLoadedClass(String name) {
502 return Class.forName(name);
503 } catch (ClassNotFoundException ex) {
509 * Sets the signers of a class. This should be invoked after defining a
513 * The <tt>Class</tt> object
516 * The signers for the class
520 protected final void setSigners(Class<?> c, Object[] signers) {
521 //c.setSigners(signers);
522 throw new UnsupportedOperationException();
529 * Finds the resource with the given name. A resource is some data
530 * (images, audio, text, etc) that can be accessed by class code in a way
531 * that is independent of the location of the code.
533 * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
534 * identifies the resource.
536 * <p> This method will first search the parent class loader for the
537 * resource; if the parent is <tt>null</tt> the path of the class loader
538 * built-in to the virtual machine is searched. That failing, this method
539 * will invoke {@link #findResource(String)} to find the resource. </p>
544 * @return A <tt>URL</tt> object for reading the resource, or
545 * <tt>null</tt> if the resource could not be found or the invoker
546 * doesn't have adequate privileges to get the resource.
550 public URL getResource(String name) {
552 if (parent != null) {
553 url = parent.getResource(name);
555 url = getBootstrapResource(name);
558 url = findResource(name);
564 * Finds all the resources with the given name. A resource is some data
565 * (images, audio, text, etc) that can be accessed by class code in a way
566 * that is independent of the location of the code.
568 * <p>The name of a resource is a <tt>/</tt>-separated path name that
569 * identifies the resource.
571 * <p> The search order is described in the documentation for {@link
572 * #getResource(String)}. </p>
577 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
578 * the resource. If no resources could be found, the enumeration
579 * will be empty. Resources that the class loader doesn't have
580 * access to will not be in the enumeration.
582 * @throws IOException
583 * If I/O errors occur
585 * @see #findResources(String)
589 public Enumeration<URL> getResources(String name) throws IOException {
590 if (this == SYSTEM) {
591 return findResources(name);
593 Enumeration[] tmp = new Enumeration[2];
594 if (parent != null) {
595 tmp[0] = parent.getResources(name);
597 tmp[0] = getBootstrapResources(name);
599 tmp[1] = findResources(name);
601 return new CompoundEnumeration(tmp);
605 * Finds the resource with the given name. Class loader implementations
606 * should override this method to specify where to find resources. </p>
611 * @return A <tt>URL</tt> object for reading the resource, or
612 * <tt>null</tt> if the resource could not be found
616 protected URL findResource(String name) {
621 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
622 * representing all the resources with the given name. Class loader
623 * implementations should override this method to specify where to load
624 * resources from. </p>
629 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
632 * @throws IOException
633 * If I/O errors occur
637 protected Enumeration<URL> findResources(String name) throws IOException {
638 return new CompoundEnumeration(new Enumeration[0]);
641 // index 0: java.lang.ClassLoader.class
642 // index 1: the immediate caller of index 0.
643 // index 2: the immediate caller of index 1.
644 private static native Class<? extends ClassLoader> getCaller(int index);
647 * Registers the caller as parallel capable.</p>
648 * The registration succeeds if and only if all of the following
649 * conditions are met: <br>
650 * 1. no instance of the caller has been created</p>
651 * 2. all of the super classes (except class Object) of the caller are
652 * registered as parallel capable</p>
653 * Note that once a class loader is registered as parallel capable, there
654 * is no way to change it back. </p>
656 * @return true if the caller is successfully registered as
657 * parallel capable and false if otherwise.
661 // protected static boolean registerAsParallelCapable() {
666 * Find a resource of the specified name from the search path used to load
667 * classes. This method locates the resource through the system class
668 * loader (see {@link #getSystemClassLoader()}). </p>
673 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
674 * resource, or <tt>null</tt> if the resource could not be found
678 public static URL getSystemResource(String name) {
679 ClassLoader system = getSystemClassLoader();
680 if (system == null) {
681 return getBootstrapResource(name);
683 return system.getResource(name);
687 * Finds all resources of the specified name from the search path used to
688 * load classes. The resources thus found are returned as an
689 * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
690 * java.net.URL <tt>URL</tt>} objects.
692 * <p> The search order is described in the documentation for {@link
693 * #getSystemResource(String)}. </p>
698 * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}
701 * @throws IOException
702 * If I/O errors occur
706 public static Enumeration<URL> getSystemResources(String name)
709 ClassLoader system = null; // getSystemClassLoader();
710 if (system == null) {
711 return getBootstrapResources(name);
713 return system.getResources(name);
719 * Returns an input stream for reading the specified resource.
721 * <p> The search order is described in the documentation for {@link
722 * #getResource(String)}. </p>
727 * @return An input stream for reading the resource, or <tt>null</tt>
728 * if the resource could not be found
732 public InputStream getResourceAsStream(String name) {
733 URL url = getResource(name);
735 return url != null ? url.openStream() : null;
736 } catch (IOException e) {
742 * Open for reading, a resource of the specified name from the search path
743 * used to load classes. This method locates the resource through the
744 * system class loader (see {@link #getSystemClassLoader()}). </p>
749 * @return An input stream for reading the resource, or <tt>null</tt>
750 * if the resource could not be found
754 public static InputStream getSystemResourceAsStream(String name) {
755 URL url = getSystemResource(name);
757 return url != null ? url.openStream() : null;
758 } catch (IOException e) {
767 * Returns the parent class loader for delegation. Some implementations may
768 * use <tt>null</tt> to represent the bootstrap class loader. This method
769 * will return <tt>null</tt> in such implementations if this class loader's
770 * parent is the bootstrap class loader.
772 * <p> If a security manager is present, and the invoker's class loader is
773 * not <tt>null</tt> and is not an ancestor of this class loader, then this
774 * method invokes the security manager's {@link
775 * SecurityManager#checkPermission(java.security.Permission)
776 * <tt>checkPermission</tt>} method with a {@link
777 * RuntimePermission#RuntimePermission(String)
778 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
779 * access to the parent class loader is permitted. If not, a
780 * <tt>SecurityException</tt> will be thrown. </p>
782 * @return The parent <tt>ClassLoader</tt>
784 * @throws SecurityException
785 * If a security manager exists and its <tt>checkPermission</tt>
786 * method doesn't allow access to this class loader's parent class
791 public final ClassLoader getParent() {
792 throw new SecurityException();
796 * Returns the system class loader for delegation. This is the default
797 * delegation parent for new <tt>ClassLoader</tt> instances, and is
798 * typically the class loader used to start the application.
800 * <p> This method is first invoked early in the runtime's startup
801 * sequence, at which point it creates the system class loader and sets it
802 * as the context class loader of the invoking <tt>Thread</tt>.
804 * <p> The default system class loader is an implementation-dependent
805 * instance of this class.
807 * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
808 * when this method is first invoked then the value of that property is
809 * taken to be the name of a class that will be returned as the system
810 * class loader. The class is loaded using the default system class loader
811 * and must define a public constructor that takes a single parameter of
812 * type <tt>ClassLoader</tt> which is used as the delegation parent. An
813 * instance is then created using this constructor with the default system
814 * class loader as the parameter. The resulting class loader is defined
815 * to be the system class loader.
817 * <p> If a security manager is present, and the invoker's class loader is
818 * not <tt>null</tt> and the invoker's class loader is not the same as or
819 * an ancestor of the system class loader, then this method invokes the
820 * security manager's {@link
821 * SecurityManager#checkPermission(java.security.Permission)
822 * <tt>checkPermission</tt>} method with a {@link
823 * RuntimePermission#RuntimePermission(String)
824 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
825 * access to the system class loader. If not, a
826 * <tt>SecurityException</tt> will be thrown. </p>
828 * @return The system <tt>ClassLoader</tt> for delegation, or
829 * <tt>null</tt> if none
831 * @throws SecurityException
832 * If a security manager exists and its <tt>checkPermission</tt>
833 * method doesn't allow access to the system class loader.
835 * @throws IllegalStateException
836 * If invoked recursively during the construction of the class
837 * loader specified by the "<tt>java.system.class.loader</tt>"
841 * If the system property "<tt>java.system.class.loader</tt>"
842 * is defined but the named class could not be loaded, the
843 * provider class does not define the required constructor, or an
844 * exception is thrown by that constructor when it is invoked. The
845 * underlying cause of the error can be retrieved via the
846 * {@link Throwable#getCause()} method.
850 public static ClassLoader getSystemClassLoader() {
851 if (SYSTEM == null) {
852 SYSTEM = new ClassLoader() {
854 protected Enumeration<URL> findResources(String name) throws IOException {
855 return getBootstrapResources(name);
859 protected URL findResource(String name) {
860 return getBootstrapResource(name);
864 protected Class<?> findClass(String name) throws ClassNotFoundException {
865 return Class.forName(name);
871 private static ClassLoader SYSTEM;
873 // Returns true if the specified class loader can be found in this class
874 // loader's delegation chain.
875 boolean isAncestor(ClassLoader cl) {
876 ClassLoader acl = this;
882 } while (acl != null);
886 private Class findBootstrapClassOrNull(String name) {
887 throw new UnsupportedOperationException();
890 private static URL getBootstrapResource(String name) {
891 return Object.class.getResource("/" + name);
894 @JavaScriptBody(args = { "name", "skip" }, body
895 = "var lb = vm.loadBytes ? vm.loadBytes : exports.loadBytes;"
896 + "return lb ? lb(name, skip) : null;"
898 static native byte[] getResourceAsStream0(String name, int skip);
900 private static Enumeration<URL> getBootstrapResources(String name) {
901 return new ResEnum(name);
904 private static class ResEnum implements Enumeration<URL> {
905 private final String name;
909 public ResEnum(String name) {
914 public boolean hasMoreElements() {
915 if (next == null && skip >= 0) {
916 byte[] arr = getResourceAsStream0(name, skip++);
918 next = Class.newResourceURL(name, arr);
926 public URL nextElement() {
929 throw new NoSuchElementException();
936 private static class OneOrZeroEnum implements Enumeration<URL> {
939 public OneOrZeroEnum(URL u) {
943 public boolean hasMoreElements() {
947 public URL nextElement() {
950 throw new NoSuchElementException();
957 private static class CompoundEnumeration implements Enumeration<URL> {
960 private final Enumeration[] arr;
962 public CompoundEnumeration(Enumeration[] arr) {
967 public boolean hasMoreElements() {
968 if (next == null && index < arr.length) {
969 if (arr[index].hasMoreElements()) {
970 next = (URL) arr[index].nextElement();
972 if (index < arr.length) {
974 return hasMoreElements();
981 public URL nextElement() {
982 if (!hasMoreElements()) {
983 throw new NoSuchElementException();