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.ByteArrayInputStream;
28 import java.io.InputStream;
29 import java.io.IOException;
31 import java.util.Enumeration;
32 import java.util.NoSuchElementException;
33 import org.apidesign.bck2brwsr.core.JavaScriptBody;
36 * A class loader is an object that is responsible for loading classes. The
37 * class <tt>ClassLoader</tt> is an abstract class. Given the <a
38 * href="#name">binary name</a> of a class, a class loader should attempt to
39 * locate or generate data that constitutes a definition for the class. A
40 * typical strategy is to transform the name into a file name and then read a
41 * "class file" of that name from a file system.
43 * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
44 * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
47 * <p> <tt>Class</tt> objects for array classes are not created by class
48 * loaders, but are created automatically as required by the Java runtime.
49 * The class loader for an array class, as returned by {@link
50 * Class#getClassLoader()} is the same as the class loader for its element
51 * type; if the element type is a primitive type, then the array class has no
54 * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
55 * extend the manner in which the Java virtual machine dynamically loads
58 * <p> Class loaders may typically be used by security managers to indicate
61 * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
62 * classes and resources. Each instance of <tt>ClassLoader</tt> has an
63 * associated parent class loader. When requested to find a class or
64 * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
65 * class or resource to its parent class loader before attempting to find the
66 * class or resource itself. The virtual machine's built-in class loader,
67 * called the "bootstrap class loader", does not itself have a parent but may
68 * serve as the parent of a <tt>ClassLoader</tt> instance.
70 * <p> Class loaders that support concurrent loading of classes are known as
71 * <em>parallel capable</em> class loaders and are required to register
72 * themselves at their class initialization time by invoking the
74 * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
75 * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
76 * capable by default. However, its subclasses still need to register themselves
77 * if they are parallel capable. <br>
78 * In environments in which the delegation model is not strictly
79 * hierarchical, class loaders need to be parallel capable, otherwise class
80 * loading can lead to deadlocks because the loader lock is held for the
81 * duration of the class loading process (see {@link #loadClass
82 * <tt>loadClass</tt>} methods).
84 * <p> Normally, the Java virtual machine loads classes from the local file
85 * system in a platform-dependent manner. For example, on UNIX systems, the
86 * virtual machine loads classes from the directory defined by the
87 * <tt>CLASSPATH</tt> environment variable.
89 * <p> However, some classes may not originate from a file; they may originate
90 * from other sources, such as the network, or they could be constructed by an
91 * application. The method {@link #defineClass(String, byte[], int, int)
92 * <tt>defineClass</tt>} converts an array of bytes into an instance of class
93 * <tt>Class</tt>. Instances of this newly defined class can be created using
94 * {@link Class#newInstance <tt>Class.newInstance</tt>}.
96 * <p> The methods and constructors of objects created by a class loader may
97 * reference other classes. To determine the class(es) referred to, the Java
98 * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
99 * the class loader that originally created the class.
101 * <p> For example, an application could create a network class loader to
102 * download class files from a server. Sample code might look like:
105 * ClassLoader loader = new NetworkClassLoader(host, port);
106 * Object main = loader.loadClass("Main", true).newInstance();
107 * . . .
108 * </pre></blockquote>
110 * <p> The network class loader subclass must define the methods {@link
111 * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
112 * from the network. Once it has downloaded the bytes that make up the class,
113 * it should use the method {@link #defineClass <tt>defineClass</tt>} to
114 * create a class instance. A sample implementation is:
117 * class NetworkClassLoader extends ClassLoader {
121 * public Class findClass(String name) {
122 * byte[] b = loadClassData(name);
123 * return defineClass(name, b, 0, b.length);
126 * private byte[] loadClassData(String name) {
127 * // load the class data from the connection
128 * . . .
131 * </pre></blockquote>
133 * <h4> <a name="name">Binary names</a> </h4>
135 * <p> Any class name provided as a {@link String} parameter to methods in
136 * <tt>ClassLoader</tt> must be a binary name as defined by
137 * <cite>The Java™ Language Specification</cite>.
139 * <p> Examples of valid class names include:
142 * "javax.swing.JSpinner$DefaultEditor"
143 * "java.security.KeyStore$Builder$FileBuilder$1"
144 * "java.net.URLClassLoader$3$1"
145 * </pre></blockquote>
147 * @see #resolveClass(Class)
150 public abstract class ClassLoader {
152 @JavaScriptBody(args = {}, body = "")
153 private static native void registerNatives();
158 // The parent class loader for delegation
159 // Note: VM hardcoded the offset of this field, thus all new fields
160 // must be added *after* it.
161 private final ClassLoader parent;
165 * Creates a new class loader using the specified parent class loader for
168 * <p> If there is a security manager, its {@link
169 * SecurityManager#checkCreateClassLoader()
170 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
171 * a security exception. </p>
174 * The parent class loader
176 * @throws SecurityException
177 * If a security manager exists and its
178 * <tt>checkCreateClassLoader</tt> method doesn't allow creation
179 * of a new class loader.
183 protected ClassLoader(ClassLoader parent) {
184 this.parent = parent;
188 * Creates a new class loader using the <tt>ClassLoader</tt> returned by
189 * the method {@link #getSystemClassLoader()
190 * <tt>getSystemClassLoader()</tt>} as the parent class loader.
192 * <p> If there is a security manager, its {@link
193 * SecurityManager#checkCreateClassLoader()
194 * <tt>checkCreateClassLoader</tt>} method is invoked. This may result in
195 * a security exception. </p>
197 * @throws SecurityException
198 * If a security manager exists and its
199 * <tt>checkCreateClassLoader</tt> method doesn't allow creation
200 * of a new class loader.
202 protected ClassLoader() {
209 * Loads the class with the specified <a href="#name">binary name</a>.
210 * This method searches for classes in the same manner as the {@link
211 * #loadClass(String, boolean)} method. It is invoked by the Java virtual
212 * machine to resolve class references. Invoking this method is equivalent
213 * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
217 * The <a href="#name">binary name</a> of the class
219 * @return The resulting <tt>Class</tt> object
221 * @throws ClassNotFoundException
222 * If the class was not found
224 public Class<?> loadClass(String name) throws ClassNotFoundException {
225 return loadClass(name, false);
229 * Loads the class with the specified <a href="#name">binary name</a>. The
230 * default implementation of this method searches for classes in the
235 * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
236 * has already been loaded. </p></li>
238 * <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
239 * on the parent class loader. If the parent is <tt>null</tt> the class
240 * loader built-in to the virtual machine is used, instead. </p></li>
242 * <li><p> Invoke the {@link #findClass(String)} method to find the
247 * <p> If the class was found using the above steps, and the
248 * <tt>resolve</tt> flag is true, this method will then invoke the {@link
249 * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
251 * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
252 * #findClass(String)}, rather than this method. </p>
254 * <p> Unless overridden, this method synchronizes on the result of
255 * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
256 * during the entire class loading process.
259 * The <a href="#name">binary name</a> of the class
262 * If <tt>true</tt> then resolve the class
264 * @return The resulting <tt>Class</tt> object
266 * @throws ClassNotFoundException
267 * If the class could not be found
269 protected Class<?> loadClass(String name, boolean resolve)
270 throws ClassNotFoundException
272 synchronized (getClassLoadingLock(name)) {
273 // First, check if the class has already been loaded
274 Class c = findLoadedClass(name);
277 if (parent != null) {
278 c = parent.loadClass(name, false);
280 c = findBootstrapClassOrNull(name);
282 } catch (ClassNotFoundException e) {
283 // ClassNotFoundException thrown if class not found
284 // from the non-null parent class loader
288 // If still not found, then invoke findClass in order
289 // to find the class.
292 // // this is the defining class loader; record the stats
293 // sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
294 // sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
295 // sun.misc.PerfCounter.getFindClasses().increment();
306 * Returns the lock object for class loading operations.
307 * For backward compatibility, the default implementation of this method
308 * behaves as follows. If this ClassLoader object is registered as
309 * parallel capable, the method returns a dedicated object associated
310 * with the specified class name. Otherwise, the method returns this
311 * ClassLoader object. </p>
314 * The name of the to-be-loaded class
316 * @return the lock for class loading operations
318 * @throws NullPointerException
319 * If registered as parallel capable and <tt>className</tt> is null
321 * @see #loadClass(String, boolean)
325 protected Object getClassLoadingLock(String className) {
331 * Finds the class with the specified <a href="#name">binary name</a>.
332 * This method should be overridden by class loader implementations that
333 * follow the delegation model for loading classes, and will be invoked by
334 * the {@link #loadClass <tt>loadClass</tt>} method after checking the
335 * parent class loader for the requested class. The default implementation
336 * throws a <tt>ClassNotFoundException</tt>. </p>
339 * The <a href="#name">binary name</a> of the class
341 * @return The resulting <tt>Class</tt> object
343 * @throws ClassNotFoundException
344 * If the class could not be found
348 protected Class<?> findClass(String name) throws ClassNotFoundException {
349 throw new ClassNotFoundException(name);
353 * Converts an array of bytes into an instance of class <tt>Class</tt>.
354 * Before the <tt>Class</tt> can be used it must be resolved. This method
355 * is deprecated in favor of the version that takes a <a
356 * href="#name">binary name</a> as its first argument, and is more secure.
359 * The bytes that make up the class data. The bytes in positions
360 * <tt>off</tt> through <tt>off+len-1</tt> should have the format
361 * of a valid class file as defined by
362 * <cite>The Java™ Virtual Machine Specification</cite>.
365 * The start offset in <tt>b</tt> of the class data
368 * The length of the class data
370 * @return The <tt>Class</tt> object that was created from the specified
373 * @throws ClassFormatError
374 * If the data did not contain a valid class
376 * @throws IndexOutOfBoundsException
377 * If either <tt>off</tt> or <tt>len</tt> is negative, or if
378 * <tt>off+len</tt> is greater than <tt>b.length</tt>.
380 * @throws SecurityException
381 * If an attempt is made to add this class to a package that
382 * contains classes that were signed by a different set of
383 * certificates than this class, or if an attempt is made
384 * to define a class in a package with a fully-qualified name
385 * that starts with "{@code java.}".
387 * @see #loadClass(String, boolean)
388 * @see #resolveClass(Class)
390 * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
391 * defineClass(String, byte[], int, int)}
394 protected final Class<?> defineClass(byte[] b, int off, int len)
395 throws ClassFormatError
397 throw new SecurityException();
401 * Converts an array of bytes into an instance of class <tt>Class</tt>.
402 * Before the <tt>Class</tt> can be used it must be resolved.
404 * <p> This method assigns a default {@link java.security.ProtectionDomain
405 * <tt>ProtectionDomain</tt>} to the newly defined class. The
406 * <tt>ProtectionDomain</tt> is effectively granted the same set of
407 * permissions returned when {@link
408 * java.security.Policy#getPermissions(java.security.CodeSource)
409 * <tt>Policy.getPolicy().getPermissions(new CodeSource(null, null))</tt>}
410 * is invoked. The default domain is created on the first invocation of
411 * {@link #defineClass(String, byte[], int, int) <tt>defineClass</tt>},
412 * and re-used on subsequent invocations.
414 * <p> To assign a specific <tt>ProtectionDomain</tt> to the class, use
415 * the {@link #defineClass(String, byte[], int, int,
416 * java.security.ProtectionDomain) <tt>defineClass</tt>} method that takes a
417 * <tt>ProtectionDomain</tt> as one of its arguments. </p>
420 * The expected <a href="#name">binary name</a> of the class, or
421 * <tt>null</tt> if not known
424 * The bytes that make up the class data. The bytes in positions
425 * <tt>off</tt> through <tt>off+len-1</tt> should have the format
426 * of a valid class file as defined by
427 * <cite>The Java™ Virtual Machine Specification</cite>.
430 * The start offset in <tt>b</tt> of the class data
433 * The length of the class data
435 * @return The <tt>Class</tt> object that was created from the specified
438 * @throws ClassFormatError
439 * If the data did not contain a valid class
441 * @throws IndexOutOfBoundsException
442 * If either <tt>off</tt> or <tt>len</tt> is negative, or if
443 * <tt>off+len</tt> is greater than <tt>b.length</tt>.
445 * @throws SecurityException
446 * If an attempt is made to add this class to a package that
447 * contains classes that were signed by a different set of
448 * certificates than this class (which is unsigned), or if
449 * <tt>name</tt> begins with "<tt>java.</tt>".
451 * @see #loadClass(String, boolean)
452 * @see #resolveClass(Class)
453 * @see java.security.CodeSource
454 * @see java.security.SecureClassLoader
458 protected final Class<?> defineClass(String name, byte[] b, int off, int len)
459 throws ClassFormatError
461 throw new SecurityException();
465 * Links the specified class. This (misleadingly named) method may be
466 * used by a class loader to link a class. If the class <tt>c</tt> has
467 * already been linked, then this method simply returns. Otherwise, the
468 * class is linked as described in the "Execution" chapter of
469 * <cite>The Java™ Language Specification</cite>.
475 * @throws NullPointerException
476 * If <tt>c</tt> is <tt>null</tt>.
478 * @see #defineClass(String, byte[], int, int)
480 protected final void resolveClass(Class<?> c) {
484 private native void resolveClass0(Class c);
488 * Returns the class with the given <a href="#name">binary name</a> if this
489 * loader has been recorded by the Java virtual machine as an initiating
490 * loader of a class with that <a href="#name">binary name</a>. Otherwise
491 * <tt>null</tt> is returned. </p>
494 * The <a href="#name">binary name</a> of the class
496 * @return The <tt>Class</tt> object, or <tt>null</tt> if the class has
501 protected final Class<?> findLoadedClass(String name) {
502 if (!checkName(name))
504 return findLoadedClass0(name);
507 private native final Class findLoadedClass0(String name);
510 * Sets the signers of a class. This should be invoked after defining a
514 * The <tt>Class</tt> object
517 * The signers for the class
521 protected final void setSigners(Class<?> c, Object[] signers) {
522 //c.setSigners(signers);
523 throw new UnsupportedOperationException();
530 * Finds the resource with the given name. A resource is some data
531 * (images, audio, text, etc) that can be accessed by class code in a way
532 * that is independent of the location of the code.
534 * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
535 * identifies the resource.
537 * <p> This method will first search the parent class loader for the
538 * resource; if the parent is <tt>null</tt> the path of the class loader
539 * built-in to the virtual machine is searched. That failing, this method
540 * will invoke {@link #findResource(String)} to find the resource. </p>
545 * @return A <tt>URL</tt> object for reading the resource, or
546 * <tt>null</tt> if the resource could not be found or the invoker
547 * doesn't have adequate privileges to get the resource.
551 public URL getResource(String name) {
553 if (parent != null) {
554 url = parent.getResource(name);
556 url = getBootstrapResource(name);
559 url = findResource(name);
565 * Finds all the resources with the given name. A resource is some data
566 * (images, audio, text, etc) that can be accessed by class code in a way
567 * that is independent of the location of the code.
569 * <p>The name of a resource is a <tt>/</tt>-separated path name that
570 * identifies the resource.
572 * <p> The search order is described in the documentation for {@link
573 * #getResource(String)}. </p>
578 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
579 * the resource. If no resources could be found, the enumeration
580 * will be empty. Resources that the class loader doesn't have
581 * access to will not be in the enumeration.
583 * @throws IOException
584 * If I/O errors occur
586 * @see #findResources(String)
590 public Enumeration<URL> getResources(String name) throws IOException {
591 if (this == SYSTEM) {
592 return findResources(name);
594 Enumeration[] tmp = new Enumeration[2];
595 if (parent != null) {
596 tmp[0] = parent.getResources(name);
598 tmp[0] = getBootstrapResources(name);
600 tmp[1] = findResources(name);
602 return new CompoundEnumeration(tmp);
606 * Finds the resource with the given name. Class loader implementations
607 * should override this method to specify where to find resources. </p>
612 * @return A <tt>URL</tt> object for reading the resource, or
613 * <tt>null</tt> if the resource could not be found
617 protected URL findResource(String name) {
622 * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
623 * representing all the resources with the given name. Class loader
624 * implementations should override this method to specify where to load
625 * resources from. </p>
630 * @return An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
633 * @throws IOException
634 * If I/O errors occur
638 protected Enumeration<URL> findResources(String name) throws IOException {
639 return new CompoundEnumeration(new Enumeration[0]);
642 // index 0: java.lang.ClassLoader.class
643 // index 1: the immediate caller of index 0.
644 // index 2: the immediate caller of index 1.
645 private static native Class<? extends ClassLoader> getCaller(int index);
648 * Registers the caller as parallel capable.</p>
649 * The registration succeeds if and only if all of the following
650 * conditions are met: <br>
651 * 1. no instance of the caller has been created</p>
652 * 2. all of the super classes (except class Object) of the caller are
653 * registered as parallel capable</p>
654 * Note that once a class loader is registered as parallel capable, there
655 * is no way to change it back. </p>
657 * @return true if the caller is successfully registered as
658 * parallel capable and false if otherwise.
662 // protected static boolean registerAsParallelCapable() {
667 * Find a resource of the specified name from the search path used to load
668 * classes. This method locates the resource through the system class
669 * loader (see {@link #getSystemClassLoader()}). </p>
674 * @return A {@link java.net.URL <tt>URL</tt>} object for reading the
675 * resource, or <tt>null</tt> if the resource could not be found
679 public static URL getSystemResource(String name) {
680 ClassLoader system = getSystemClassLoader();
681 if (system == null) {
682 return getBootstrapResource(name);
684 return system.getResource(name);
688 * Finds all resources of the specified name from the search path used to
689 * load classes. The resources thus found are returned as an
690 * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
691 * java.net.URL <tt>URL</tt>} objects.
693 * <p> The search order is described in the documentation for {@link
694 * #getSystemResource(String)}. </p>
699 * @return An enumeration of resource {@link java.net.URL <tt>URL</tt>}
702 * @throws IOException
703 * If I/O errors occur
707 public static Enumeration<URL> getSystemResources(String name)
710 ClassLoader system = null; // getSystemClassLoader();
711 if (system == null) {
712 return getBootstrapResources(name);
714 return system.getResources(name);
720 * Returns an input stream for reading the specified resource.
722 * <p> The search order is described in the documentation for {@link
723 * #getResource(String)}. </p>
728 * @return An input stream for reading the resource, or <tt>null</tt>
729 * if the resource could not be found
733 public InputStream getResourceAsStream(String name) {
734 URL url = getResource(name);
736 return url != null ? url.openStream() : null;
737 } catch (IOException e) {
743 * Open for reading, a resource of the specified name from the search path
744 * used to load classes. This method locates the resource through the
745 * system class loader (see {@link #getSystemClassLoader()}). </p>
750 * @return An input stream for reading the resource, or <tt>null</tt>
751 * if the resource could not be found
755 public static InputStream getSystemResourceAsStream(String name) {
756 URL url = getSystemResource(name);
758 return url != null ? url.openStream() : null;
759 } catch (IOException e) {
768 * Returns the parent class loader for delegation. Some implementations may
769 * use <tt>null</tt> to represent the bootstrap class loader. This method
770 * will return <tt>null</tt> in such implementations if this class loader's
771 * parent is the bootstrap class loader.
773 * <p> If a security manager is present, and the invoker's class loader is
774 * not <tt>null</tt> and is not an ancestor of this class loader, then this
775 * method invokes the security manager's {@link
776 * SecurityManager#checkPermission(java.security.Permission)
777 * <tt>checkPermission</tt>} method with a {@link
778 * RuntimePermission#RuntimePermission(String)
779 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
780 * access to the parent class loader is permitted. If not, a
781 * <tt>SecurityException</tt> will be thrown. </p>
783 * @return The parent <tt>ClassLoader</tt>
785 * @throws SecurityException
786 * If a security manager exists and its <tt>checkPermission</tt>
787 * method doesn't allow access to this class loader's parent class
792 public final ClassLoader getParent() {
793 throw new SecurityException();
797 * Returns the system class loader for delegation. This is the default
798 * delegation parent for new <tt>ClassLoader</tt> instances, and is
799 * typically the class loader used to start the application.
801 * <p> This method is first invoked early in the runtime's startup
802 * sequence, at which point it creates the system class loader and sets it
803 * as the context class loader of the invoking <tt>Thread</tt>.
805 * <p> The default system class loader is an implementation-dependent
806 * instance of this class.
808 * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
809 * when this method is first invoked then the value of that property is
810 * taken to be the name of a class that will be returned as the system
811 * class loader. The class is loaded using the default system class loader
812 * and must define a public constructor that takes a single parameter of
813 * type <tt>ClassLoader</tt> which is used as the delegation parent. An
814 * instance is then created using this constructor with the default system
815 * class loader as the parameter. The resulting class loader is defined
816 * to be the system class loader.
818 * <p> If a security manager is present, and the invoker's class loader is
819 * not <tt>null</tt> and the invoker's class loader is not the same as or
820 * an ancestor of the system class loader, then this method invokes the
821 * security manager's {@link
822 * SecurityManager#checkPermission(java.security.Permission)
823 * <tt>checkPermission</tt>} method with a {@link
824 * RuntimePermission#RuntimePermission(String)
825 * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
826 * access to the system class loader. If not, a
827 * <tt>SecurityException</tt> will be thrown. </p>
829 * @return The system <tt>ClassLoader</tt> for delegation, or
830 * <tt>null</tt> if none
832 * @throws SecurityException
833 * If a security manager exists and its <tt>checkPermission</tt>
834 * method doesn't allow access to the system class loader.
836 * @throws IllegalStateException
837 * If invoked recursively during the construction of the class
838 * loader specified by the "<tt>java.system.class.loader</tt>"
842 * If the system property "<tt>java.system.class.loader</tt>"
843 * is defined but the named class could not be loaded, the
844 * provider class does not define the required constructor, or an
845 * exception is thrown by that constructor when it is invoked. The
846 * underlying cause of the error can be retrieved via the
847 * {@link Throwable#getCause()} method.
851 public static ClassLoader getSystemClassLoader() {
852 if (SYSTEM == null) {
853 SYSTEM = new ClassLoader() {
855 protected Enumeration<URL> findResources(String name) throws IOException {
856 return getBootstrapResources(name);
860 protected URL findResource(String name) {
861 return getBootstrapResource(name);
865 protected Class<?> findClass(String name) throws ClassNotFoundException {
866 return Class.forName(name);
872 private static ClassLoader SYSTEM;
874 // Returns true if the specified class loader can be found in this class
875 // loader's delegation chain.
876 boolean isAncestor(ClassLoader cl) {
877 ClassLoader acl = this;
883 } while (acl != null);
887 private boolean checkName(String name) {
888 throw new UnsupportedOperationException();
891 private Class findBootstrapClassOrNull(String name) {
892 throw new UnsupportedOperationException();
895 private static URL getBootstrapResource(String name) {
896 return Object.class.getResource("/" + name);
899 @JavaScriptBody(args = { "name", "skip" }, body
900 = "var lb = vm.loadBytes ? vm.loadBytes : exports.loadBytes;"
901 + "return lb ? lb(name, skip) : null;"
903 static native byte[] getResourceAsStream0(String name, int skip);
905 private static Enumeration<URL> getBootstrapResources(String name) {
906 return new ResEnum(name);
909 private static class ResEnum implements Enumeration<URL> {
910 private final String name;
914 public ResEnum(String name) {
919 public boolean hasMoreElements() {
920 if (next == null && skip >= 0) {
921 byte[] arr = getResourceAsStream0(name, skip++);
923 next = Class.newResourceURL(name, new ByteArrayInputStream(arr));
931 public URL nextElement() {
934 throw new NoSuchElementException();
941 private static class OneOrZeroEnum implements Enumeration<URL> {
944 public OneOrZeroEnum(URL u) {
948 public boolean hasMoreElements() {
952 public URL nextElement() {
955 throw new NoSuchElementException();
962 private static class CompoundEnumeration implements Enumeration<URL> {
965 private final Enumeration[] arr;
967 public CompoundEnumeration(Enumeration[] arr) {
972 public boolean hasMoreElements() {
973 if (next == null && index < arr.length) {
974 if (arr[index].hasMoreElements()) {
975 next = (URL) arr[index].nextElement();
977 if (index < arr.length) {
979 return hasMoreElements();
986 public URL nextElement() {
987 if (!hasMoreElements()) {
988 throw new NoSuchElementException();