1 /*
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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.
10 *
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).
16 *
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.
20 *
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
23 * questions.
24 */
25
26 package java.lang;
27
28 import java.io.InputStream;
29 import java.io.IOException;
30 import java.io.UncheckedIOException;
31 import java.io.File;
32 import java.lang.reflect.Constructor;
33 import java.lang.reflect.InvocationTargetException;
34 import java.net.URL;
35 import java.security.AccessController;
36 import java.security.AccessControlContext;
37 import java.security.CodeSource;
38 import java.security.PrivilegedAction;
39 import java.security.ProtectionDomain;
40 import java.security.cert.Certificate;
41 import java.util.ArrayDeque;
42 import java.util.Arrays;
43 import java.util.Collections;
44 import java.util.Deque;
45 import java.util.Enumeration;
46 import java.util.HashMap;
47 import java.util.HashSet;
48 import java.util.Hashtable;
49 import java.util.Map;
50 import java.util.NoSuchElementException;
51 import java.util.Objects;
52 import java.util.Set;
53 import java.util.Spliterator;
54 import java.util.Spliterators;
55 import java.util.Vector;
56 import java.util.WeakHashMap;
57 import java.util.concurrent.ConcurrentHashMap;
58 import java.util.function.Supplier;
59 import java.util.stream.Stream;
60 import java.util.stream.StreamSupport;
61
62 import jdk.internal.loader.BuiltinClassLoader;
63 import jdk.internal.perf.PerfCounter;
64 import jdk.internal.loader.BootLoader;
65 import jdk.internal.loader.ClassLoaders;
66 import jdk.internal.misc.Unsafe;
67 import jdk.internal.misc.VM;
68 import jdk.internal.ref.CleanerFactory;
69 import jdk.internal.reflect.CallerSensitive;
70 import jdk.internal.reflect.Reflection;
71 import sun.reflect.misc.ReflectUtil;
72 import sun.security.util.SecurityConstants;
73
74 /**
75 * A class loader is an object that is responsible for loading classes. The
76 * class {@code ClassLoader} is an abstract class. Given the <a
77 * href="#binary-name">binary name</a> of a class, a class loader should attempt to
78 * locate or generate data that constitutes a definition for the class. A
79 * typical strategy is to transform the name into a file name and then read a
80 * "class file" of that name from a file system.
81 *
82 * <p> Every {@link java.lang.Class Class} object contains a {@link
83 * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
84 * it.
85 *
86 * <p> {@code Class} objects for array classes are not created by class
87 * loaders, but are created automatically as required by the Java runtime.
88 * The class loader for an array class, as returned by {@link
89 * Class#getClassLoader()} is the same as the class loader for its element
90 * type; if the element type is a primitive type, then the array class has no
91 * class loader.
92 *
93 * <p> Applications implement subclasses of {@code ClassLoader} in order to
94 * extend the manner in which the Java virtual machine dynamically loads
95 * classes.
96 *
97 * <p> Class loaders may typically be used by security managers to indicate
98 * security domains.
99 *
100 * <p> In addition to loading classes, a class loader is also responsible for
101 * locating resources. A resource is some data (a "{@code .class}" file,
102 * configuration data, or an image for example) that is identified with an
103 * abstract '/'-separated path name. Resources are typically packaged with an
104 * application or library so that they can be located by code in the
105 * application or library. In some cases, the resources are included so that
106 * they can be located by other libraries.
107 *
108 * <p> The {@code ClassLoader} class uses a delegation model to search for
109 * classes and resources. Each instance of {@code ClassLoader} has an
110 * associated parent class loader. When requested to find a class or
111 * resource, a {@code ClassLoader} instance will usually delegate the search
112 * for the class or resource to its parent class loader before attempting to
113 * find the class or resource itself.
114 *
115 * <p> Class loaders that support concurrent loading of classes are known as
116 * <em>{@linkplain #isRegisteredAsParallelCapable() parallel capable}</em> class
117 * loaders and are required to register themselves at their class initialization
118 * time by invoking the {@link
119 * #registerAsParallelCapable ClassLoader.registerAsParallelCapable}
120 * method. Note that the {@code ClassLoader} class is registered as parallel
121 * capable by default. However, its subclasses still need to register themselves
122 * if they are parallel capable.
123 * In environments in which the delegation model is not strictly
124 * hierarchical, class loaders need to be parallel capable, otherwise class
125 * loading can lead to deadlocks because the loader lock is held for the
126 * duration of the class loading process (see {@link #loadClass
127 * loadClass} methods).
128 *
129 * <h3> <a id="builtinLoaders">Run-time Built-in Class Loaders</a></h3>
130 *
131 * The Java run-time has the following built-in class loaders:
132 *
133 * <ul>
134 * <li><p>Bootstrap class loader.
135 * It is the virtual machine's built-in class loader, typically represented
136 * as {@code null}, and does not have a parent.</li>
137 * <li><p>{@linkplain #getPlatformClassLoader() Platform class loader}.
138 * All <em>platform classes</em> are visible to the platform class loader
139 * that can be used as the parent of a {@code ClassLoader} instance.
140 * Platform classes include Java SE platform APIs, their implementation
141 * classes and JDK-specific run-time classes that are defined by the
142 * platform class loader or its ancestors.
143 * <p> To allow for upgrading/overriding of modules defined to the platform
144 * class loader, and where upgraded modules read modules defined to class
145 * loaders other than the platform class loader and its ancestors, then
146 * the platform class loader may have to delegate to other class loaders,
147 * the application class loader for example.
148 * In other words, classes in named modules defined to class loaders
149 * other than the platform class loader and its ancestors may be visible
150 * to the platform class loader. </li>
151 * <li><p>{@linkplain #getSystemClassLoader() System class loader}.
152 * It is also known as <em>application class loader</em> and is distinct
153 * from the platform class loader.
154 * The system class loader is typically used to define classes on the
155 * application class path, module path, and JDK-specific tools.
156 * The platform class loader is a parent or an ancestor of the system class
157 * loader that all platform classes are visible to it.</li>
158 * </ul>
159 *
160 * <p> Normally, the Java virtual machine loads classes from the local file
161 * system in a platform-dependent manner.
162 * However, some classes may not originate from a file; they may originate
163 * from other sources, such as the network, or they could be constructed by an
164 * application. The method {@link #defineClass(String, byte[], int, int)
165 * defineClass} converts an array of bytes into an instance of class
166 * {@code Class}. Instances of this newly defined class can be created using
167 * {@link Class#newInstance Class.newInstance}.
168 *
169 * <p> The methods and constructors of objects created by a class loader may
170 * reference other classes. To determine the class(es) referred to, the Java
171 * virtual machine invokes the {@link #loadClass loadClass} method of
172 * the class loader that originally created the class.
173 *
174 * <p> For example, an application could create a network class loader to
175 * download class files from a server. Sample code might look like:
176 *
177 * <blockquote><pre>
178 * ClassLoader loader = new NetworkClassLoader(host, port);
179 * Object main = loader.loadClass("Main", true).newInstance();
180 * . . .
181 * </pre></blockquote>
182 *
183 * <p> The network class loader subclass must define the methods {@link
184 * #findClass findClass} and {@code loadClassData} to load a class
185 * from the network. Once it has downloaded the bytes that make up the class,
186 * it should use the method {@link #defineClass defineClass} to
187 * create a class instance. A sample implementation is:
188 *
189 * <blockquote><pre>
190 * class NetworkClassLoader extends ClassLoader {
191 * String host;
192 * int port;
193 *
194 * public Class findClass(String name) {
195 * byte[] b = loadClassData(name);
196 * return defineClass(name, b, 0, b.length);
197 * }
198 *
199 * private byte[] loadClassData(String name) {
200 * // load the class data from the connection
201 * . . .
202 * }
203 * }
204 * </pre></blockquote>
205 *
206 * <h3> <a id="binary-name">Binary names</a> </h3>
207 *
208 * <p> Any class name provided as a {@code String} parameter to methods in
209 * {@code ClassLoader} must be a binary name as defined by
210 * <cite>The Java™ Language Specification</cite>.
211 *
212 * <p> Examples of valid class names include:
213 * <blockquote><pre>
214 * "java.lang.String"
215 * "javax.swing.JSpinner$DefaultEditor"
216 * "java.security.KeyStore$Builder$FileBuilder$1"
217 * "java.net.URLClassLoader$3$1"
218 * </pre></blockquote>
219 *
220 * <p> Any package name provided as a {@code String} parameter to methods in
221 * {@code ClassLoader} must be either the empty string (denoting an unnamed package)
222 * or a fully qualified name as defined by
223 * <cite>The Java™ Language Specification</cite>.
224 *
225 * @jls 6.7 Fully Qualified Names
226 * @jls 13.1 The Form of a Binary
227 * @see #resolveClass(Class)
228 * @since 1.0
229 * @revised 9
230 * @spec JPMS
231 */
232 public abstract class ClassLoader {
233
234 private static native void registerNatives();
235 static {
236 registerNatives();
237 }
238
239 // The parent class loader for delegation
240 // Note: VM hardcoded the offset of this field, thus all new fields
241 // must be added *after* it.
242 private final ClassLoader parent;
243
244 // class loader name
245 private final String name;
246
247 // the unnamed module for this ClassLoader
248 private final Module unnamedModule;
249
250 // a string for exception message printing
251 private final String nameAndId;
252
253 /**
254 * Encapsulates the set of parallel capable loader types.
255 */
256 private static class ParallelLoaders {
257 private ParallelLoaders() {}
258
259 // the set of parallel capable loader types
260 private static final Set<Class<? extends ClassLoader>> loaderTypes =
261 Collections.newSetFromMap(new WeakHashMap<>());
262 static {
263 synchronized (loaderTypes) { loaderTypes.add(ClassLoader.class); }
264 }
265
266 /**
267 * Registers the given class loader type as parallel capable.
268 * Returns {@code true} is successfully registered; {@code false} if
269 * loader's super class is not registered.
270 */
271 static boolean register(Class<? extends ClassLoader> c) {
272 synchronized (loaderTypes) {
273 if (loaderTypes.contains(c.getSuperclass())) {
274 // register the class loader as parallel capable
275 // if and only if all of its super classes are.
276 // Note: given current classloading sequence, if
277 // the immediate super class is parallel capable,
278 // all the super classes higher up must be too.
279 loaderTypes.add(c);
280 return true;
281 } else {
282 return false;
283 }
284 }
285 }
286
287 /**
288 * Returns {@code true} if the given class loader type is
289 * registered as parallel capable.
290 */
291 static boolean isRegistered(Class<? extends ClassLoader> c) {
292 synchronized (loaderTypes) {
293 return loaderTypes.contains(c);
294 }
295 }
296 }
297
298 // Maps class name to the corresponding lock object when the current
299 // class loader is parallel capable.
300 // Note: VM also uses this field to decide if the current class loader
301 // is parallel capable and the appropriate lock object for class loading.
302 private final ConcurrentHashMap<String, Object> parallelLockMap;
303
304 // Maps packages to certs
305 private final Map <String, Certificate[]> package2certs;
306
307 // Shared among all packages with unsigned classes
308 private static final Certificate[] nocerts = new Certificate[0];
309
310 // The classes loaded by this class loader. The only purpose of this table
311 // is to keep the classes from being GC'ed until the loader is GC'ed.
312 private final Vector<Class<?>> classes = new Vector<>();
313
314 // The "default" domain. Set as the default ProtectionDomain on newly
315 // created classes.
316 private final ProtectionDomain defaultDomain =
317 new ProtectionDomain(new CodeSource(null, (Certificate[]) null),
318 null, this, null);
319
320 // Invoked by the VM to record every loaded class with this loader.
321 void addClass(Class<?> c) {
322 classes.addElement(c);
323 }
324
325 // The packages defined in this class loader. Each package name is
326 // mapped to its corresponding NamedPackage object.
327 //
328 // The value is a Package object if ClassLoader::definePackage,
329 // Class::getPackage, ClassLoader::getDefinePackage(s) or
330 // Package::getPackage(s) method is called to define it.
331 // Otherwise, the value is a NamedPackage object.
332 private final ConcurrentHashMap<String, NamedPackage> packages
333 = new ConcurrentHashMap<>();
334
335 /*
336 * Returns a named package for the given module.
337 */
338 private NamedPackage getNamedPackage(String pn, Module m) {
339 NamedPackage p = packages.get(pn);
340 if (p == null) {
341 p = new NamedPackage(pn, m);
342
343 NamedPackage value = packages.putIfAbsent(pn, p);
344 if (value != null) {
345 // Package object already be defined for the named package
346 p = value;
347 // if definePackage is called by this class loader to define
348 // a package in a named module, this will return Package
349 // object of the same name. Package object may contain
350 // unexpected information but it does not impact the runtime.
351 // this assertion may be helpful for troubleshooting
352 assert value.module() == m;
353 }
354 }
355 return p;
356 }
357
358 private static Void checkCreateClassLoader() {
359 return checkCreateClassLoader(null);
360 }
361
362 private static Void checkCreateClassLoader(String name) {
363 if (name != null && name.isEmpty()) {
364 throw new IllegalArgumentException("name must be non-empty or null");
365 }
366
367 SecurityManager security = System.getSecurityManager();
368 if (security != null) {
369 security.checkCreateClassLoader();
370 }
371 return null;
372 }
373
374 private ClassLoader(Void unused, String name, ClassLoader parent) {
375 this.name = name;
376 this.parent = parent;
377 this.unnamedModule = new Module(this);
378 if (ParallelLoaders.isRegistered(this.getClass())) {
379 parallelLockMap = new ConcurrentHashMap<>();
380 package2certs = new ConcurrentHashMap<>();
381 assertionLock = new Object();
382 } else {
383 // no finer-grained lock; lock on the classloader instance
384 parallelLockMap = null;
385 package2certs = new Hashtable<>();
386 assertionLock = this;
387 }
388 this.nameAndId = nameAndId(this);
389 }
390
391 /**
392 * If the defining loader has a name explicitly set then
393 * '<loader-name>' @<id>
394 * If the defining loader has no name then
395 * <qualified-class-name> @<id>
396 * If it's built-in loader then omit `@<id>` as there is only one instance.
397 */
398 private static String nameAndId(ClassLoader ld) {
399 String nid = ld.getName() != null ? "\'" + ld.getName() + "\'"
400 : ld.getClass().getName();
401 if (!(ld instanceof BuiltinClassLoader)) {
402 String id = Integer.toHexString(System.identityHashCode(ld));
403 nid = nid + " @" + id;
404 }
405 return nid;
406 }
407
408 /**
409 * Creates a new class loader of the specified name and using the
410 * specified parent class loader for delegation.
411 *
412 * @apiNote If the parent is specified as {@code null} (for the
413 * bootstrap class loader) then there is no guarantee that all platform
414 * classes are visible.
415 *
416 * @param name class loader name; or {@code null} if not named
417 * @param parent the parent class loader
418 *
419 * @throws IllegalArgumentException if the given name is empty.
420 *
421 * @throws SecurityException
422 * If a security manager exists and its
423 * {@link SecurityManager#checkCreateClassLoader()}
424 * method doesn't allow creation of a new class loader.
425 *
426 * @since 9
427 * @spec JPMS
428 */
429 protected ClassLoader(String name, ClassLoader parent) {
430 this(checkCreateClassLoader(name), name, parent);
431 }
432
433 /**
434 * Creates a new class loader using the specified parent class loader for
435 * delegation.
436 *
437 * <p> If there is a security manager, its {@link
438 * SecurityManager#checkCreateClassLoader() checkCreateClassLoader} method
439 * is invoked. This may result in a security exception. </p>
440 *
441 * @apiNote If the parent is specified as {@code null} (for the
442 * bootstrap class loader) then there is no guarantee that all platform
443 * classes are visible.
444 *
445 * @param parent
446 * The parent class loader
447 *
448 * @throws SecurityException
449 * If a security manager exists and its
450 * {@code checkCreateClassLoader} method doesn't allow creation
451 * of a new class loader.
452 *
453 * @since 1.2
454 */
455 protected ClassLoader(ClassLoader parent) {
456 this(checkCreateClassLoader(), null, parent);
457 }
458
459 /**
460 * Creates a new class loader using the {@code ClassLoader} returned by
461 * the method {@link #getSystemClassLoader()
462 * getSystemClassLoader()} as the parent class loader.
463 *
464 * <p> If there is a security manager, its {@link
465 * SecurityManager#checkCreateClassLoader()
466 * checkCreateClassLoader} method is invoked. This may result in
467 * a security exception. </p>
468 *
469 * @throws SecurityException
470 * If a security manager exists and its
471 * {@code checkCreateClassLoader} method doesn't allow creation
472 * of a new class loader.
473 */
474 protected ClassLoader() {
475 this(checkCreateClassLoader(), null, getSystemClassLoader());
476 }
477
478 /**
479 * Returns the name of this class loader or {@code null} if
480 * this class loader is not named.
481 *
482 * @apiNote This method is non-final for compatibility. If this
483 * method is overridden, this method must return the same name
484 * as specified when this class loader was instantiated.
485 *
486 * @return name of this class loader; or {@code null} if
487 * this class loader is not named.
488 *
489 * @since 9
490 * @spec JPMS
491 */
492 public String getName() {
493 return name;
494 }
495
496 // package-private used by StackTraceElement to avoid
497 // calling the overrideable getName method
498 final String name() {
499 return name;
500 }
501
502 // -- Class --
503
504 /**
505 * Loads the class with the specified <a href="#binary-name">binary name</a>.
506 * This method searches for classes in the same manner as the {@link
507 * #loadClass(String, boolean)} method. It is invoked by the Java virtual
508 * machine to resolve class references. Invoking this method is equivalent
509 * to invoking {@link #loadClass(String, boolean) loadClass(name,
510 * false)}.
511 *
512 * @param name
513 * The <a href="#binary-name">binary name</a> of the class
514 *
515 * @return The resulting {@code Class} object
516 *
517 * @throws ClassNotFoundException
518 * If the class was not found
519 */
520 public Class<?> loadClass(String name) throws ClassNotFoundException {
521 return loadClass(name, false);
522 }
523
524 /**
525 * Loads the class with the specified <a href="#binary-name">binary name</a>. The
526 * default implementation of this method searches for classes in the
527 * following order:
528 *
529 * <ol>
530 *
531 * <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
532 * has already been loaded. </p></li>
533 *
534 * <li><p> Invoke the {@link #loadClass(String) loadClass} method
535 * on the parent class loader. If the parent is {@code null} the class
536 * loader built into the virtual machine is used, instead. </p></li>
537 *
538 * <li><p> Invoke the {@link #findClass(String)} method to find the
539 * class. </p></li>
540 *
541 * </ol>
542 *
543 * <p> If the class was found using the above steps, and the
544 * {@code resolve} flag is true, this method will then invoke the {@link
545 * #resolveClass(Class)} method on the resulting {@code Class} object.
546 *
547 * <p> Subclasses of {@code ClassLoader} are encouraged to override {@link
548 * #findClass(String)}, rather than this method. </p>
549 *
550 * <p> Unless overridden, this method synchronizes on the result of
551 * {@link #getClassLoadingLock getClassLoadingLock} method
552 * during the entire class loading process.
553 *
554 * @param name
555 * The <a href="#binary-name">binary name</a> of the class
556 *
557 * @param resolve
558 * If {@code true} then resolve the class
559 *
560 * @return The resulting {@code Class} object
561 *
562 * @throws ClassNotFoundException
563 * If the class could not be found
564 */
565 protected Class<?> loadClass(String name, boolean resolve)
566 throws ClassNotFoundException
567 {
568 synchronized (getClassLoadingLock(name)) {
569 // First, check if the class has already been loaded
570 Class<?> c = findLoadedClass(name);
571 if (c == null) {
572 long t0 = System.nanoTime();
573 try {
574 if (parent != null) {
575 c = parent.loadClass(name, false);
576 } else {
577 c = findBootstrapClassOrNull(name);
578 }
579 } catch (ClassNotFoundException e) {
580 // ClassNotFoundException thrown if class not found
581 // from the non-null parent class loader
582 }
583
584 if (c == null) {
585 // If still not found, then invoke findClass in order
586 // to find the class.
587 long t1 = System.nanoTime();
588 c = findClass(name);
589
590 // this is the defining class loader; record the stats
591 PerfCounter.getParentDelegationTime().addTime(t1 - t0);
592 PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
593 PerfCounter.getFindClasses().increment();
594 }
595 }
596 if (resolve) {
597 resolveClass(c);
598 }
599 return c;
600 }
601 }
602
603 /**
604 * Loads the class with the specified <a href="#binary-name">binary name</a>
605 * in a module defined to this class loader. This method returns {@code null}
606 * if the class could not be found.
607 *
608 * @apiNote This method does not delegate to the parent class loader.
609 *
610 * @implSpec The default implementation of this method searches for classes
611 * in the following order:
612 *
613 * <ol>
614 * <li>Invoke {@link #findLoadedClass(String)} to check if the class
615 * has already been loaded.</li>
616 * <li>Invoke the {@link #findClass(String, String)} method to find the
617 * class in the given module.</li>
618 * </ol>
619 *
620 * @param module
621 * The module
622 * @param name
623 * The <a href="#binary-name">binary name</a> of the class
624 *
625 * @return The resulting {@code Class} object in a module defined by
626 * this class loader, or {@code null} if the class could not be found.
627 */
628 final Class<?> loadClass(Module module, String name) {
629 synchronized (getClassLoadingLock(name)) {
630 // First, check if the class has already been loaded
631 Class<?> c = findLoadedClass(name);
632 if (c == null) {
633 c = findClass(module.getName(), name);
634 }
635 if (c != null && c.getModule() == module) {
636 return c;
637 } else {
638 return null;
639 }
640 }
641 }
642
643 /**
644 * Returns the lock object for class loading operations.
645 * For backward compatibility, the default implementation of this method
646 * behaves as follows. If this ClassLoader object is registered as
647 * parallel capable, the method returns a dedicated object associated
648 * with the specified class name. Otherwise, the method returns this
649 * ClassLoader object.
650 *
651 * @param className
652 * The name of the to-be-loaded class
653 *
654 * @return the lock for class loading operations
655 *
656 * @throws NullPointerException
657 * If registered as parallel capable and {@code className} is null
658 *
659 * @see #loadClass(String, boolean)
660 *
661 * @since 1.7
662 */
663 protected Object getClassLoadingLock(String className) {
664 Object lock = this;
665 if (parallelLockMap != null) {
666 Object newLock = new Object();
667 lock = parallelLockMap.putIfAbsent(className, newLock);
668 if (lock == null) {
669 lock = newLock;
670 }
671 }
672 return lock;
673 }
674
675 // Invoked by the VM after loading class with this loader.
676 private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
677 final SecurityManager sm = System.getSecurityManager();
678 if (sm != null) {
679 if (ReflectUtil.isNonPublicProxyClass(cls)) {
680 for (Class<?> intf: cls.getInterfaces()) {
681 checkPackageAccess(intf, pd);
682 }
683 return;
684 }
685
686 final String packageName = cls.getPackageName();
687 if (!packageName.isEmpty()) {
688 AccessController.doPrivileged(new PrivilegedAction<>() {
689 public Void run() {
690 sm.checkPackageAccess(packageName);
691 return null;
692 }
693 }, new AccessControlContext(new ProtectionDomain[] {pd}));
694 }
695 }
696 }
697
698 /**
699 * Finds the class with the specified <a href="#binary-name">binary name</a>.
700 * This method should be overridden by class loader implementations that
701 * follow the delegation model for loading classes, and will be invoked by
702 * the {@link #loadClass loadClass} method after checking the
703 * parent class loader for the requested class.
704 *
705 * @implSpec The default implementation throws {@code ClassNotFoundException}.
706 *
707 * @param name
708 * The <a href="#binary-name">binary name</a> of the class
709 *
710 * @return The resulting {@code Class} object
711 *
712 * @throws ClassNotFoundException
713 * If the class could not be found
714 *
715 * @since 1.2
716 */
717 protected Class<?> findClass(String name) throws ClassNotFoundException {
718 throw new ClassNotFoundException(name);
719 }
720
721 /**
722 * Finds the class with the given <a href="#binary-name">binary name</a>
723 * in a module defined to this class loader.
724 * Class loader implementations that support loading from modules
725 * should override this method.
726 *
727 * @apiNote This method returns {@code null} rather than throwing
728 * {@code ClassNotFoundException} if the class could not be found.
729 *
730 * @implSpec The default implementation attempts to find the class by
731 * invoking {@link #findClass(String)} when the {@code moduleName} is
732 * {@code null}. It otherwise returns {@code null}.
733 *
734 * @param moduleName
735 * The module name; or {@code null} to find the class in the
736 * {@linkplain #getUnnamedModule() unnamed module} for this
737 * class loader
738
739 * @param name
740 * The <a href="#binary-name">binary name</a> of the class
741 *
742 * @return The resulting {@code Class} object, or {@code null}
743 * if the class could not be found.
744 *
745 * @since 9
746 * @spec JPMS
747 */
748 protected Class<?> findClass(String moduleName, String name) {
749 if (moduleName == null) {
750 try {
751 return findClass(name);
752 } catch (ClassNotFoundException ignore) { }
753 }
754 return null;
755 }
756
757
758 /**
759 * Converts an array of bytes into an instance of class {@code Class}.
760 * Before the {@code Class} can be used it must be resolved. This method
761 * is deprecated in favor of the version that takes a <a
762 * href="#binary-name">binary name</a> as its first argument, and is more secure.
763 *
764 * @param b
765 * The bytes that make up the class data. The bytes in positions
766 * {@code off} through {@code off+len-1} should have the format
767 * of a valid class file as defined by
768 * <cite>The Java™ Virtual Machine Specification</cite>.
769 *
770 * @param off
771 * The start offset in {@code b} of the class data
772 *
773 * @param len
774 * The length of the class data
775 *
776 * @return The {@code Class} object that was created from the specified
777 * class data
778 *
779 * @throws ClassFormatError
780 * If the data did not contain a valid class
781 *
782 * @throws IndexOutOfBoundsException
783 * If either {@code off} or {@code len} is negative, or if
784 * {@code off+len} is greater than {@code b.length}.
785 *
786 * @throws SecurityException
787 * If an attempt is made to add this class to a package that
788 * contains classes that were signed by a different set of
789 * certificates than this class, or if an attempt is made
790 * to define a class in a package with a fully-qualified name
791 * that starts with "{@code java.}".
792 *
793 * @see #loadClass(String, boolean)
794 * @see #resolveClass(Class)
795 *
796 * @deprecated Replaced by {@link #defineClass(String, byte[], int, int)
797 * defineClass(String, byte[], int, int)}
798 */
799 @Deprecated(since="1.1")
800 protected final Class<?> defineClass(byte[] b, int off, int len)
801 throws ClassFormatError
802 {
803 return defineClass(null, b, off, len, null);
804 }
805
806 /**
807 * Converts an array of bytes into an instance of class {@code Class}.
808 * Before the {@code Class} can be used it must be resolved.
809 *
810 * <p> This method assigns a default {@link java.security.ProtectionDomain
811 * ProtectionDomain} to the newly defined class. The
812 * {@code ProtectionDomain} is effectively granted the same set of
813 * permissions returned when {@link
814 * java.security.Policy#getPermissions(java.security.CodeSource)
815 * Policy.getPolicy().getPermissions(new CodeSource(null, null))}
816 * is invoked. The default protection domain is created on the first invocation
817 * of {@link #defineClass(String, byte[], int, int) defineClass},
818 * and re-used on subsequent invocations.
819 *
820 * <p> To assign a specific {@code ProtectionDomain} to the class, use
821 * the {@link #defineClass(String, byte[], int, int,
822 * java.security.ProtectionDomain) defineClass} method that takes a
823 * {@code ProtectionDomain} as one of its arguments. </p>
824 *
825 * <p>
826 * This method defines a package in this class loader corresponding to the
827 * package of the {@code Class} (if such a package has not already been defined
828 * in this class loader). The name of the defined package is derived from
829 * the <a href="#binary-name">binary name</a> of the class specified by
830 * the byte array {@code b}.
831 * Other properties of the defined package are as specified by {@link Package}.
832 *
833 * @param name
834 * The expected <a href="#binary-name">binary name</a> of the class, or
835 * {@code null} if not known
836 *
837 * @param b
838 * The bytes that make up the class data. The bytes in positions
839 * {@code off} through {@code off+len-1} should have the format
840 * of a valid class file as defined by
841 * <cite>The Java™ Virtual Machine Specification</cite>.
842 *
843 * @param off
844 * The start offset in {@code b} of the class data
845 *
846 * @param len
847 * The length of the class data
848 *
849 * @return The {@code Class} object that was created from the specified
850 * class data.
851 *
852 * @throws ClassFormatError
853 * If the data did not contain a valid class
854 *
855 * @throws IndexOutOfBoundsException
856 * If either {@code off} or {@code len} is negative, or if
857 * {@code off+len} is greater than {@code b.length}.
858 *
859 * @throws SecurityException
860 * If an attempt is made to add this class to a package that
861 * contains classes that were signed by a different set of
862 * certificates than this class (which is unsigned), or if
863 * {@code name} begins with "{@code java.}".
864 *
865 * @see #loadClass(String, boolean)
866 * @see #resolveClass(Class)
867 * @see java.security.CodeSource
868 * @see java.security.SecureClassLoader
869 *
870 * @since 1.1
871 * @revised 9
872 * @spec JPMS
873 */
874 protected final Class<?> defineClass(String name, byte[] b, int off, int len)
875 throws ClassFormatError
876 {
877 return defineClass(name, b, off, len, null);
878 }
879
880 /* Determine protection domain, and check that:
881 - not define java.* class,
882 - signer of this class matches signers for the rest of the classes in
883 package.
884 */
885 private ProtectionDomain preDefineClass(String name,
886 ProtectionDomain pd)
887 {
888 if (!checkName(name))
889 throw new NoClassDefFoundError("IllegalName: " + name);
890
891 // Note: Checking logic in java.lang.invoke.MemberName.checkForTypeAlias
892 // relies on the fact that spoofing is impossible if a class has a name
893 // of the form "java.*"
894 if ((name != null) && name.startsWith("java.")
895 && this != getBuiltinPlatformClassLoader()) {
896 throw new SecurityException
897 ("Prohibited package name: " +
898 name.substring(0, name.lastIndexOf('.')));
899 }
900 if (pd == null) {
901 pd = defaultDomain;
902 }
903
904 if (name != null) {
905 checkCerts(name, pd.getCodeSource());
906 }
907
908 return pd;
909 }
910
911 private String defineClassSourceLocation(ProtectionDomain pd) {
912 CodeSource cs = pd.getCodeSource();
913 String source = null;
914 if (cs != null && cs.getLocation() != null) {
915 source = cs.getLocation().toString();
916 }
917 return source;
918 }
919
920 private void postDefineClass(Class<?> c, ProtectionDomain pd) {
921 // define a named package, if not present
922 getNamedPackage(c.getPackageName(), c.getModule());
923
924 if (pd.getCodeSource() != null) {
925 Certificate certs[] = pd.getCodeSource().getCertificates();
926 if (certs != null)
927 setSigners(c, certs);
928 }
929 }
930
931 /**
932 * Converts an array of bytes into an instance of class {@code Class},
933 * with a given {@code ProtectionDomain}.
934 *
935 * <p> If the given {@code ProtectionDomain} is {@code null},
936 * then a default protection domain will be assigned to the class as specified
937 * in the documentation for {@link #defineClass(String, byte[], int, int)}.
938 * Before the class can be used it must be resolved.
939 *
940 * <p> The first class defined in a package determines the exact set of
941 * certificates that all subsequent classes defined in that package must
942 * contain. The set of certificates for a class is obtained from the
943 * {@link java.security.CodeSource CodeSource} within the
944 * {@code ProtectionDomain} of the class. Any classes added to that
945 * package must contain the same set of certificates or a
946 * {@code SecurityException} will be thrown. Note that if
947 * {@code name} is {@code null}, this check is not performed.
948 * You should always pass in the <a href="#binary-name">binary name</a> of the
949 * class you are defining as well as the bytes. This ensures that the
950 * class you are defining is indeed the class you think it is.
951 *
952 * <p> If the specified {@code name} begins with "{@code java.}", it can
953 * only be defined by the {@linkplain #getPlatformClassLoader()
954 * platform class loader} or its ancestors; otherwise {@code SecurityException}
955 * will be thrown. If {@code name} is not {@code null}, it must be equal to
956 * the <a href="#binary-name">binary name</a> of the class
957 * specified by the byte array {@code b}, otherwise a {@link
958 * NoClassDefFoundError NoClassDefFoundError} will be thrown.
959 *
960 * <p> This method defines a package in this class loader corresponding to the
961 * package of the {@code Class} (if such a package has not already been defined
962 * in this class loader). The name of the defined package is derived from
963 * the <a href="#binary-name">binary name</a> of the class specified by
964 * the byte array {@code b}.
965 * Other properties of the defined package are as specified by {@link Package}.
966 *
967 * @param name
968 * The expected <a href="#binary-name">binary name</a> of the class, or
969 * {@code null} if not known
970 *
971 * @param b
972 * The bytes that make up the class data. The bytes in positions
973 * {@code off} through {@code off+len-1} should have the format
974 * of a valid class file as defined by
975 * <cite>The Java™ Virtual Machine Specification</cite>.
976 *
977 * @param off
978 * The start offset in {@code b} of the class data
979 *
980 * @param len
981 * The length of the class data
982 *
983 * @param protectionDomain
984 * The {@code ProtectionDomain} of the class
985 *
986 * @return The {@code Class} object created from the data,
987 * and {@code ProtectionDomain}.
988 *
989 * @throws ClassFormatError
990 * If the data did not contain a valid class
991 *
992 * @throws NoClassDefFoundError
993 * If {@code name} is not {@code null} and not equal to the
994 * <a href="#binary-name">binary name</a> of the class specified by {@code b}
995 *
996 * @throws IndexOutOfBoundsException
997 * If either {@code off} or {@code len} is negative, or if
998 * {@code off+len} is greater than {@code b.length}.
999 *
1000 * @throws SecurityException
1001 * If an attempt is made to add this class to a package that
1002 * contains classes that were signed by a different set of
1003 * certificates than this class, or if {@code name} begins with
1004 * "{@code java.}" and this class loader is not the platform
1005 * class loader or its ancestor.
1006 *
1007 * @revised 9
1008 * @spec JPMS
1009 */
1010 protected final Class<?> defineClass(String name, byte[] b, int off, int len,
1011 ProtectionDomain protectionDomain)
1012 throws ClassFormatError
1013 {
1014 protectionDomain = preDefineClass(name, protectionDomain);
1015 String source = defineClassSourceLocation(protectionDomain);
1016 Class<?> c = defineClass1(this, name, b, off, len, protectionDomain, source);
1017 postDefineClass(c, protectionDomain);
1018 return c;
1019 }
1020
1021 /**
1022 * Converts a {@link java.nio.ByteBuffer ByteBuffer} into an instance
1023 * of class {@code Class}, with the given {@code ProtectionDomain}.
1024 * If the given {@code ProtectionDomain} is {@code null}, then a default
1025 * protection domain will be assigned to the class as
1026 * specified in the documentation for {@link #defineClass(String, byte[],
1027 * int, int)}. Before the class can be used it must be resolved.
1028 *
1029 * <p>The rules about the first class defined in a package determining the
1030 * set of certificates for the package, the restrictions on class names,
1031 * and the defined package of the class
1032 * are identical to those specified in the documentation for {@link
1033 * #defineClass(String, byte[], int, int, ProtectionDomain)}.
1034 *
1035 * <p> An invocation of this method of the form
1036 * <i>cl</i>{@code .defineClass(}<i>name</i>{@code ,}
1037 * <i>bBuffer</i>{@code ,} <i>pd</i>{@code )} yields exactly the same
1038 * result as the statements
1039 *
1040 *<p> <code>
1041 * ...<br>
1042 * byte[] temp = new byte[bBuffer.{@link
1043 * java.nio.ByteBuffer#remaining remaining}()];<br>
1044 * bBuffer.{@link java.nio.ByteBuffer#get(byte[])
1045 * get}(temp);<br>
1046 * return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
1047 * cl.defineClass}(name, temp, 0,
1048 * temp.length, pd);<br>
1049 * </code></p>
1050 *
1051 * @param name
1052 * The expected <a href="#binary-name">binary name</a>. of the class, or
1053 * {@code null} if not known
1054 *
1055 * @param b
1056 * The bytes that make up the class data. The bytes from positions
1057 * {@code b.position()} through {@code b.position() + b.limit() -1
1058 * } should have the format of a valid class file as defined by
1059 * <cite>The Java™ Virtual Machine Specification</cite>.
1060 *
1061 * @param protectionDomain
1062 * The {@code ProtectionDomain} of the class, or {@code null}.
1063 *
1064 * @return The {@code Class} object created from the data,
1065 * and {@code ProtectionDomain}.
1066 *
1067 * @throws ClassFormatError
1068 * If the data did not contain a valid class.
1069 *
1070 * @throws NoClassDefFoundError
1071 * If {@code name} is not {@code null} and not equal to the
1072 * <a href="#binary-name">binary name</a> of the class specified by {@code b}
1073 *
1074 * @throws SecurityException
1075 * If an attempt is made to add this class to a package that
1076 * contains classes that were signed by a different set of
1077 * certificates than this class, or if {@code name} begins with
1078 * "{@code java.}".
1079 *
1080 * @see #defineClass(String, byte[], int, int, ProtectionDomain)
1081 *
1082 * @since 1.5
1083 * @revised 9
1084 * @spec JPMS
1085 */
1086 protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
1087 ProtectionDomain protectionDomain)
1088 throws ClassFormatError
1089 {
1090 int len = b.remaining();
1091
1092 // Use byte[] if not a direct ByteBuffer:
1093 if (!b.isDirect()) {
1094 if (b.hasArray()) {
1095 return defineClass(name, b.array(),
1096 b.position() + b.arrayOffset(), len,
1097 protectionDomain);
1098 } else {
1099 // no array, or read-only array
1100 byte[] tb = new byte[len];
1101 b.get(tb); // get bytes out of byte buffer.
1102 return defineClass(name, tb, 0, len, protectionDomain);
1103 }
1104 }
1105
1106 protectionDomain = preDefineClass(name, protectionDomain);
1107 String source = defineClassSourceLocation(protectionDomain);
1108 Class<?> c = defineClass2(this, name, b, b.position(), len, protectionDomain, source);
1109 postDefineClass(c, protectionDomain);
1110 return c;
1111 }
1112
1113 static native Class<?> defineClass1(ClassLoader loader, String name, byte[] b, int off, int len,
1114 ProtectionDomain pd, String source);
1115
1116 static native Class<?> defineClass2(ClassLoader loader, String name, java.nio.ByteBuffer b,
1117 int off, int len, ProtectionDomain pd,
1118 String source);
1119
1120 // true if the name is null or has the potential to be a valid binary name
1121 private boolean checkName(String name) {
1122 if ((name == null) || (name.isEmpty()))
1123 return true;
1124 if ((name.indexOf('/') != -1) || (name.charAt(0) == '['))
1125 return false;
1126 return true;
1127 }
1128
1129 private void checkCerts(String name, CodeSource cs) {
1130 int i = name.lastIndexOf('.');
1131 String pname = (i == -1) ? "" : name.substring(0, i);
1132
1133 Certificate[] certs = null;
1134 if (cs != null) {
1135 certs = cs.getCertificates();
1136 }
1137 Certificate[] pcerts = null;
1138 if (parallelLockMap == null) {
1139 synchronized (this) {
1140 pcerts = package2certs.get(pname);
1141 if (pcerts == null) {
1142 package2certs.put(pname, (certs == null? nocerts:certs));
1143 }
1144 }
1145 } else {
1146 pcerts = ((ConcurrentHashMap<String, Certificate[]>)package2certs).
1147 putIfAbsent(pname, (certs == null? nocerts:certs));
1148 }
1149 if (pcerts != null && !compareCerts(pcerts, certs)) {
1150 throw new SecurityException("class \"" + name
1151 + "\"'s signer information does not match signer information"
1152 + " of other classes in the same package");
1153 }
1154 }
1155
1156 /**
1157 * check to make sure the certs for the new class (certs) are the same as
1158 * the certs for the first class inserted in the package (pcerts)
1159 */
1160 private boolean compareCerts(Certificate[] pcerts,
1161 Certificate[] certs)
1162 {
1163 // certs can be null, indicating no certs.
1164 if ((certs == null) || (certs.length == 0)) {
1165 return pcerts.length == 0;
1166 }
1167
1168 // the length must be the same at this point
1169 if (certs.length != pcerts.length)
1170 return false;
1171
1172 // go through and make sure all the certs in one array
1173 // are in the other and vice-versa.
1174 boolean match;
1175 for (Certificate cert : certs) {
1176 match = false;
1177 for (Certificate pcert : pcerts) {
1178 if (cert.equals(pcert)) {
1179 match = true;
1180 break;
1181 }
1182 }
1183 if (!match) return false;
1184 }
1185
1186 // now do the same for pcerts
1187 for (Certificate pcert : pcerts) {
1188 match = false;
1189 for (Certificate cert : certs) {
1190 if (pcert.equals(cert)) {
1191 match = true;
1192 break;
1193 }
1194 }
1195 if (!match) return false;
1196 }
1197
1198 return true;
1199 }
1200
1201 /**
1202 * Links the specified class. This (misleadingly named) method may be
1203 * used by a class loader to link a class. If the class {@code c} has
1204 * already been linked, then this method simply returns. Otherwise, the
1205 * class is linked as described in the "Execution" chapter of
1206 * <cite>The Java™ Language Specification</cite>.
1207 *
1208 * @param c
1209 * The class to link
1210 *
1211 * @throws NullPointerException
1212 * If {@code c} is {@code null}.
1213 *
1214 * @see #defineClass(String, byte[], int, int)
1215 */
1216 protected final void resolveClass(Class<?> c) {
1217 if (c == null) {
1218 throw new NullPointerException();
1219 }
1220 }
1221
1222 /**
1223 * Finds a class with the specified <a href="#binary-name">binary name</a>,
1224 * loading it if necessary.
1225 *
1226 * <p> This method loads the class through the system class loader (see
1227 * {@link #getSystemClassLoader()}). The {@code Class} object returned
1228 * might have more than one {@code ClassLoader} associated with it.
1229 * Subclasses of {@code ClassLoader} need not usually invoke this method,
1230 * because most class loaders need to override just {@link
1231 * #findClass(String)}. </p>
1232 *
1233 * @param name
1234 * The <a href="#binary-name">binary name</a> of the class
1235 *
1236 * @return The {@code Class} object for the specified {@code name}
1237 *
1238 * @throws ClassNotFoundException
1239 * If the class could not be found
1240 *
1241 * @see #ClassLoader(ClassLoader)
1242 * @see #getParent()
1243 */
1244 protected final Class<?> findSystemClass(String name)
1245 throws ClassNotFoundException
1246 {
1247 return getSystemClassLoader().loadClass(name);
1248 }
1249
1250 /**
1251 * Returns a class loaded by the bootstrap class loader;
1252 * or return null if not found.
1253 */
1254 Class<?> findBootstrapClassOrNull(String name) {
1255 if (!checkName(name)) return null;
1256
1257 return findBootstrapClass(name);
1258 }
1259
1260 // return null if not found
1261 private native Class<?> findBootstrapClass(String name);
1262
1263 /**
1264 * Returns the class with the given <a href="#binary-name">binary name</a> if this
1265 * loader has been recorded by the Java virtual machine as an initiating
1266 * loader of a class with that <a href="#binary-name">binary name</a>. Otherwise
1267 * {@code null} is returned.
1268 *
1269 * @param name
1270 * The <a href="#binary-name">binary name</a> of the class
1271 *
1272 * @return The {@code Class} object, or {@code null} if the class has
1273 * not been loaded
1274 *
1275 * @since 1.1
1276 */
1277 protected final Class<?> findLoadedClass(String name) {
1278 if (!checkName(name))
1279 return null;
1280 return findLoadedClass0(name);
1281 }
1282
1283 private final native Class<?> findLoadedClass0(String name);
1284
1285 /**
1286 * Sets the signers of a class. This should be invoked after defining a
1287 * class.
1288 *
1289 * @param c
1290 * The {@code Class} object
1291 *
1292 * @param signers
1293 * The signers for the class
1294 *
1295 * @since 1.1
1296 */
1297 protected final void setSigners(Class<?> c, Object[] signers) {
1298 c.setSigners(signers);
1299 }
1300
1301
1302 // -- Resources --
1303
1304 /**
1305 * Returns a URL to a resource in a module defined to this class loader.
1306 * Class loader implementations that support loading from modules
1307 * should override this method.
1308 *
1309 * @apiNote This method is the basis for the {@link
1310 * Class#getResource Class.getResource}, {@link Class#getResourceAsStream
1311 * Class.getResourceAsStream}, and {@link Module#getResourceAsStream
1312 * Module.getResourceAsStream} methods. It is not subject to the rules for
1313 * encapsulation specified by {@code Module.getResourceAsStream}.
1314 *
1315 * @implSpec The default implementation attempts to find the resource by
1316 * invoking {@link #findResource(String)} when the {@code moduleName} is
1317 * {@code null}. It otherwise returns {@code null}.
1318 *
1319 * @param moduleName
1320 * The module name; or {@code null} to find a resource in the
1321 * {@linkplain #getUnnamedModule() unnamed module} for this
1322 * class loader
1323 * @param name
1324 * The resource name
1325 *
1326 * @return A URL to the resource; {@code null} if the resource could not be
1327 * found, a URL could not be constructed to locate the resource,
1328 * access to the resource is denied by the security manager, or
1329 * there isn't a module of the given name defined to the class
1330 * loader.
1331 *
1332 * @throws IOException
1333 * If I/O errors occur
1334 *
1335 * @see java.lang.module.ModuleReader#find(String)
1336 * @since 9
1337 * @spec JPMS
1338 */
1339 protected URL findResource(String moduleName, String name) throws IOException {
1340 if (moduleName == null) {
1341 return findResource(name);
1342 } else {
1343 return null;
1344 }
1345 }
1346
1347 /**
1348 * Finds the resource with the given name. A resource is some data
1349 * (images, audio, text, etc) that can be accessed by class code in a way
1350 * that is independent of the location of the code.
1351 *
1352 * <p> The name of a resource is a '{@code /}'-separated path name that
1353 * identifies the resource. </p>
1354 *
1355 * <p> Resources in named modules are subject to the encapsulation rules
1356 * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
1357 * Additionally, and except for the special case where the resource has a
1358 * name ending with "{@code .class}", this method will only find resources in
1359 * packages of named modules when the package is {@link Module#isOpen(String)
1360 * opened} unconditionally (even if the caller of this method is in the
1361 * same module as the resource). </p>
1362 *
1363 * @implSpec The default implementation will first search the parent class
1364 * loader for the resource; if the parent is {@code null} the path of the
1365 * class loader built into the virtual machine is searched. If not found,
1366 * this method will invoke {@link #findResource(String)} to find the resource.
1367 *
1368 * @apiNote Where several modules are defined to the same class loader,
1369 * and where more than one module contains a resource with the given name,
1370 * then the ordering that modules are searched is not specified and may be
1371 * very unpredictable.
1372 * When overriding this method it is recommended that an implementation
1373 * ensures that any delegation is consistent with the {@link
1374 * #getResources(java.lang.String) getResources(String)} method.
1375 *
1376 * @param name
1377 * The resource name
1378 *
1379 * @return {@code URL} object for reading the resource; {@code null} if
1380 * the resource could not be found, a {@code URL} could not be
1381 * constructed to locate the resource, the resource is in a package
1382 * that is not opened unconditionally, or access to the resource is
1383 * denied by the security manager.
1384 *
1385 * @throws NullPointerException If {@code name} is {@code null}
1386 *
1387 * @since 1.1
1388 * @revised 9
1389 * @spec JPMS
1390 */
1391 public URL getResource(String name) {
1392 Objects.requireNonNull(name);
1393 URL url;
1394 if (parent != null) {
1395 url = parent.getResource(name);
1396 } else {
1397 url = BootLoader.findResource(name);
1398 }
1399 if (url == null) {
1400 url = findResource(name);
1401 }
1402 return url;
1403 }
1404
1405 /**
1406 * Finds all the resources with the given name. A resource is some data
1407 * (images, audio, text, etc) that can be accessed by class code in a way
1408 * that is independent of the location of the code.
1409 *
1410 * <p> The name of a resource is a {@code /}-separated path name that
1411 * identifies the resource. </p>
1412 *
1413 * <p> Resources in named modules are subject to the encapsulation rules
1414 * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
1415 * Additionally, and except for the special case where the resource has a
1416 * name ending with "{@code .class}", this method will only find resources in
1417 * packages of named modules when the package is {@link Module#isOpen(String)
1418 * opened} unconditionally (even if the caller of this method is in the
1419 * same module as the resource). </p>
1420 *
1421 * @implSpec The default implementation will first search the parent class
1422 * loader for the resource; if the parent is {@code null} the path of the
1423 * class loader built into the virtual machine is searched. It then
1424 * invokes {@link #findResources(String)} to find the resources with the
1425 * name in this class loader. It returns an enumeration whose elements
1426 * are the URLs found by searching the parent class loader followed by
1427 * the elements found with {@code findResources}.
1428 *
1429 * @apiNote Where several modules are defined to the same class loader,
1430 * and where more than one module contains a resource with the given name,
1431 * then the ordering is not specified and may be very unpredictable.
1432 * When overriding this method it is recommended that an
1433 * implementation ensures that any delegation is consistent with the {@link
1434 * #getResource(java.lang.String) getResource(String)} method. This should
1435 * ensure that the first element returned by the Enumeration's
1436 * {@code nextElement} method is the same resource that the
1437 * {@code getResource(String)} method would return.
1438 *
1439 * @param name
1440 * The resource name
1441 *
1442 * @return An enumeration of {@link java.net.URL URL} objects for the
1443 * resource. If no resources could be found, the enumeration will
1444 * be empty. Resources for which a {@code URL} cannot be
1445 * constructed, are in a package that is not opened
1446 * unconditionally, or access to the resource is denied by the
1447 * security manager, are not returned in the enumeration.
1448 *
1449 * @throws IOException
1450 * If I/O errors occur
1451 * @throws NullPointerException If {@code name} is {@code null}
1452 *
1453 * @since 1.2
1454 * @revised 9
1455 * @spec JPMS
1456 */
1457 public Enumeration<URL> getResources(String name) throws IOException {
1458 Objects.requireNonNull(name);
1459 @SuppressWarnings("unchecked")
1460 Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
1461 if (parent != null) {
1462 tmp[0] = parent.getResources(name);
1463 } else {
1464 tmp[0] = BootLoader.findResources(name);
1465 }
1466 tmp[1] = findResources(name);
1467
1468 return new CompoundEnumeration<>(tmp);
1469 }
1470
1471 /**
1472 * Returns a stream whose elements are the URLs of all the resources with
1473 * the given name. A resource is some data (images, audio, text, etc) that
1474 * can be accessed by class code in a way that is independent of the
1475 * location of the code.
1476 *
1477 * <p> The name of a resource is a {@code /}-separated path name that
1478 * identifies the resource.
1479 *
1480 * <p> The resources will be located when the returned stream is evaluated.
1481 * If the evaluation results in an {@code IOException} then the I/O
1482 * exception is wrapped in an {@link UncheckedIOException} that is then
1483 * thrown.
1484 *
1485 * <p> Resources in named modules are subject to the encapsulation rules
1486 * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
1487 * Additionally, and except for the special case where the resource has a
1488 * name ending with "{@code .class}", this method will only find resources in
1489 * packages of named modules when the package is {@link Module#isOpen(String)
1490 * opened} unconditionally (even if the caller of this method is in the
1491 * same module as the resource). </p>
1492 *
1493 * @implSpec The default implementation invokes {@link #getResources(String)
1494 * getResources} to find all the resources with the given name and returns
1495 * a stream with the elements in the enumeration as the source.
1496 *
1497 * @apiNote When overriding this method it is recommended that an
1498 * implementation ensures that any delegation is consistent with the {@link
1499 * #getResource(java.lang.String) getResource(String)} method. This should
1500 * ensure that the first element returned by the stream is the same
1501 * resource that the {@code getResource(String)} method would return.
1502 *
1503 * @param name
1504 * The resource name
1505 *
1506 * @return A stream of resource {@link java.net.URL URL} objects. If no
1507 * resources could be found, the stream will be empty. Resources
1508 * for which a {@code URL} cannot be constructed, are in a package
1509 * that is not opened unconditionally, or access to the resource
1510 * is denied by the security manager, will not be in the stream.
1511 *
1512 * @throws NullPointerException If {@code name} is {@code null}
1513 *
1514 * @since 9
1515 */
1516 public Stream<URL> resources(String name) {
1517 Objects.requireNonNull(name);
1518 int characteristics = Spliterator.NONNULL | Spliterator.IMMUTABLE;
1519 Supplier<Spliterator<URL>> si = () -> {
1520 try {
1521 return Spliterators.spliteratorUnknownSize(
1522 getResources(name).asIterator(), characteristics);
1523 } catch (IOException e) {
1524 throw new UncheckedIOException(e);
1525 }
1526 };
1527 return StreamSupport.stream(si, characteristics, false);
1528 }
1529
1530 /**
1531 * Finds the resource with the given name. Class loader implementations
1532 * should override this method.
1533 *
1534 * <p> For resources in named modules then the method must implement the
1535 * rules for encapsulation specified in the {@code Module} {@link
1536 * Module#getResourceAsStream getResourceAsStream} method. Additionally,
1537 * it must not find non-"{@code .class}" resources in packages of named
1538 * modules unless the package is {@link Module#isOpen(String) opened}
1539 * unconditionally. </p>
1540 *
1541 * @implSpec The default implementation returns {@code null}.
1542 *
1543 * @param name
1544 * The resource name
1545 *
1546 * @return {@code URL} object for reading the resource; {@code null} if
1547 * the resource could not be found, a {@code URL} could not be
1548 * constructed to locate the resource, the resource is in a package
1549 * that is not opened unconditionally, or access to the resource is
1550 * denied by the security manager.
1551 *
1552 * @since 1.2
1553 * @revised 9
1554 * @spec JPMS
1555 */
1556 protected URL findResource(String name) {
1557 return null;
1558 }
1559
1560 /**
1561 * Returns an enumeration of {@link java.net.URL URL} objects
1562 * representing all the resources with the given name. Class loader
1563 * implementations should override this method.
1564 *
1565 * <p> For resources in named modules then the method must implement the
1566 * rules for encapsulation specified in the {@code Module} {@link
1567 * Module#getResourceAsStream getResourceAsStream} method. Additionally,
1568 * it must not find non-"{@code .class}" resources in packages of named
1569 * modules unless the package is {@link Module#isOpen(String) opened}
1570 * unconditionally. </p>
1571 *
1572 * @implSpec The default implementation returns an enumeration that
1573 * contains no elements.
1574 *
1575 * @param name
1576 * The resource name
1577 *
1578 * @return An enumeration of {@link java.net.URL URL} objects for
1579 * the resource. If no resources could be found, the enumeration
1580 * will be empty. Resources for which a {@code URL} cannot be
1581 * constructed, are in a package that is not opened unconditionally,
1582 * or access to the resource is denied by the security manager,
1583 * are not returned in the enumeration.
1584 *
1585 * @throws IOException
1586 * If I/O errors occur
1587 *
1588 * @since 1.2
1589 * @revised 9
1590 * @spec JPMS
1591 */
1592 protected Enumeration<URL> findResources(String name) throws IOException {
1593 return Collections.emptyEnumeration();
1594 }
1595
1596 /**
1597 * Registers the caller as
1598 * {@linkplain #isRegisteredAsParallelCapable() parallel capable}.
1599 * The registration succeeds if and only if all of the following
1600 * conditions are met:
1601 * <ol>
1602 * <li> no instance of the caller has been created</li>
1603 * <li> all of the super classes (except class Object) of the caller are
1604 * registered as parallel capable</li>
1605 * </ol>
1606 * <p>Note that once a class loader is registered as parallel capable, there
1607 * is no way to change it back.</p>
1608 *
1609 * @return {@code true} if the caller is successfully registered as
1610 * parallel capable and {@code false} if otherwise.
1611 *
1612 * @see #isRegisteredAsParallelCapable()
1613 *
1614 * @since 1.7
1615 */
1616 @CallerSensitive
1617 protected static boolean registerAsParallelCapable() {
1618 Class<? extends ClassLoader> callerClass =
1619 Reflection.getCallerClass().asSubclass(ClassLoader.class);
1620 return ParallelLoaders.register(callerClass);
1621 }
1622
1623 /**
1624 * Returns {@code true} if this class loader is registered as
1625 * {@linkplain #registerAsParallelCapable parallel capable}, otherwise
1626 * {@code false}.
1627 *
1628 * @return {@code true} if this class loader is parallel capable,
1629 * otherwise {@code false}.
1630 *
1631 * @see #registerAsParallelCapable()
1632 *
1633 * @since 9
1634 */
1635 public final boolean isRegisteredAsParallelCapable() {
1636 return ParallelLoaders.isRegistered(this.getClass());
1637 }
1638
1639 /**
1640 * Find a resource of the specified name from the search path used to load
1641 * classes. This method locates the resource through the system class
1642 * loader (see {@link #getSystemClassLoader()}).
1643 *
1644 * <p> Resources in named modules are subject to the encapsulation rules
1645 * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
1646 * Additionally, and except for the special case where the resource has a
1647 * name ending with "{@code .class}", this method will only find resources in
1648 * packages of named modules when the package is {@link Module#isOpen(String)
1649 * opened} unconditionally. </p>
1650 *
1651 * @param name
1652 * The resource name
1653 *
1654 * @return A {@link java.net.URL URL} to the resource; {@code
1655 * null} if the resource could not be found, a URL could not be
1656 * constructed to locate the resource, the resource is in a package
1657 * that is not opened unconditionally or access to the resource is
1658 * denied by the security manager.
1659 *
1660 * @since 1.1
1661 * @revised 9
1662 * @spec JPMS
1663 */
1664 public static URL getSystemResource(String name) {
1665 return getSystemClassLoader().getResource(name);
1666 }
1667
1668 /**
1669 * Finds all resources of the specified name from the search path used to
1670 * load classes. The resources thus found are returned as an
1671 * {@link java.util.Enumeration Enumeration} of {@link
1672 * java.net.URL URL} objects.
1673 *
1674 * <p> The search order is described in the documentation for {@link
1675 * #getSystemResource(String)}. </p>
1676 *
1677 * <p> Resources in named modules are subject to the encapsulation rules
1678 * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
1679 * Additionally, and except for the special case where the resource has a
1680 * name ending with "{@code .class}", this method will only find resources in
1681 * packages of named modules when the package is {@link Module#isOpen(String)
1682 * opened} unconditionally. </p>
1683 *
1684 * @param name
1685 * The resource name
1686 *
1687 * @return An enumeration of {@link java.net.URL URL} objects for
1688 * the resource. If no resources could be found, the enumeration
1689 * will be empty. Resources for which a {@code URL} cannot be
1690 * constructed, are in a package that is not opened unconditionally,
1691 * or access to the resource is denied by the security manager,
1692 * are not returned in the enumeration.
1693 *
1694 * @throws IOException
1695 * If I/O errors occur
1696 *
1697 * @since 1.2
1698 * @revised 9
1699 * @spec JPMS
1700 */
1701 public static Enumeration<URL> getSystemResources(String name)
1702 throws IOException
1703 {
1704 return getSystemClassLoader().getResources(name);
1705 }
1706
1707 /**
1708 * Returns an input stream for reading the specified resource.
1709 *
1710 * <p> The search order is described in the documentation for {@link
1711 * #getResource(String)}. </p>
1712 *
1713 * <p> Resources in named modules are subject to the encapsulation rules
1714 * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
1715 * Additionally, and except for the special case where the resource has a
1716 * name ending with "{@code .class}", this method will only find resources in
1717 * packages of named modules when the package is {@link Module#isOpen(String)
1718 * opened} unconditionally. </p>
1719 *
1720 * @param name
1721 * The resource name
1722 *
1723 * @return An input stream for reading the resource; {@code null} if the
1724 * resource could not be found, the resource is in a package that
1725 * is not opened unconditionally, or access to the resource is
1726 * denied by the security manager.
1727 *
1728 * @throws NullPointerException If {@code name} is {@code null}
1729 *
1730 * @since 1.1
1731 * @revised 9
1732 * @spec JPMS
1733 */
1734 public InputStream getResourceAsStream(String name) {
1735 Objects.requireNonNull(name);
1736 URL url = getResource(name);
1737 try {
1738 return url != null ? url.openStream() : null;
1739 } catch (IOException e) {
1740 return null;
1741 }
1742 }
1743
1744 /**
1745 * Open for reading, a resource of the specified name from the search path
1746 * used to load classes. This method locates the resource through the
1747 * system class loader (see {@link #getSystemClassLoader()}).
1748 *
1749 * <p> Resources in named modules are subject to the encapsulation rules
1750 * specified by {@link Module#getResourceAsStream Module.getResourceAsStream}.
1751 * Additionally, and except for the special case where the resource has a
1752 * name ending with "{@code .class}", this method will only find resources in
1753 * packages of named modules when the package is {@link Module#isOpen(String)
1754 * opened} unconditionally. </p>
1755 *
1756 * @param name
1757 * The resource name
1758 *
1759 * @return An input stream for reading the resource; {@code null} if the
1760 * resource could not be found, the resource is in a package that
1761 * is not opened unconditionally, or access to the resource is
1762 * denied by the security manager.
1763 *
1764 * @since 1.1
1765 * @revised 9
1766 * @spec JPMS
1767 */
1768 public static InputStream getSystemResourceAsStream(String name) {
1769 URL url = getSystemResource(name);
1770 try {
1771 return url != null ? url.openStream() : null;
1772 } catch (IOException e) {
1773 return null;
1774 }
1775 }
1776
1777
1778 // -- Hierarchy --
1779
1780 /**
1781 * Returns the parent class loader for delegation. Some implementations may
1782 * use {@code null} to represent the bootstrap class loader. This method
1783 * will return {@code null} in such implementations if this class loader's
1784 * parent is the bootstrap class loader.
1785 *
1786 * @return The parent {@code ClassLoader}
1787 *
1788 * @throws SecurityException
1789 * If a security manager is present, and the caller's class loader
1790 * is not {@code null} and is not an ancestor of this class loader,
1791 * and the caller does not have the
1792 * {@link RuntimePermission}{@code ("getClassLoader")}
1793 *
1794 * @since 1.2
1795 */
1796 @CallerSensitive
1797 public final ClassLoader getParent() {
1798 if (parent == null)
1799 return null;
1800 SecurityManager sm = System.getSecurityManager();
1801 if (sm != null) {
1802 // Check access to the parent class loader
1803 // If the caller's class loader is same as this class loader,
1804 // permission check is performed.
1805 checkClassLoaderPermission(parent, Reflection.getCallerClass());
1806 }
1807 return parent;
1808 }
1809
1810 /**
1811 * Returns the unnamed {@code Module} for this class loader.
1812 *
1813 * @return The unnamed Module for this class loader
1814 *
1815 * @see Module#isNamed()
1816 * @since 9
1817 * @spec JPMS
1818 */
1819 public final Module getUnnamedModule() {
1820 return unnamedModule;
1821 }
1822
1823 /**
1824 * Returns the platform class loader. All
1825 * <a href="#builtinLoaders">platform classes</a> are visible to
1826 * the platform class loader.
1827 *
1828 * @implNote The name of the builtin platform class loader is
1829 * {@code "platform"}.
1830 *
1831 * @return The platform {@code ClassLoader}.
1832 *
1833 * @throws SecurityException
1834 * If a security manager is present, and the caller's class loader is
1835 * not {@code null}, and the caller's class loader is not the same
1836 * as or an ancestor of the platform class loader,
1837 * and the caller does not have the
1838 * {@link RuntimePermission}{@code ("getClassLoader")}
1839 *
1840 * @since 9
1841 * @spec JPMS
1842 */
1843 @CallerSensitive
1844 public static ClassLoader getPlatformClassLoader() {
1845 SecurityManager sm = System.getSecurityManager();
1846 ClassLoader loader = getBuiltinPlatformClassLoader();
1847 if (sm != null) {
1848 checkClassLoaderPermission(loader, Reflection.getCallerClass());
1849 }
1850 return loader;
1851 }
1852
1853 /**
1854 * Returns the system class loader. This is the default
1855 * delegation parent for new {@code ClassLoader} instances, and is
1856 * typically the class loader used to start the application.
1857 *
1858 * <p> This method is first invoked early in the runtime's startup
1859 * sequence, at which point it creates the system class loader. This
1860 * class loader will be the context class loader for the main application
1861 * thread (for example, the thread that invokes the {@code main} method of
1862 * the main class).
1863 *
1864 * <p> The default system class loader is an implementation-dependent
1865 * instance of this class.
1866 *
1867 * <p> If the system property "{@code java.system.class.loader}" is defined
1868 * when this method is first invoked then the value of that property is
1869 * taken to be the name of a class that will be returned as the system
1870 * class loader. The class is loaded using the default system class loader
1871 * and must define a public constructor that takes a single parameter of
1872 * type {@code ClassLoader} which is used as the delegation parent. An
1873 * instance is then created using this constructor with the default system
1874 * class loader as the parameter. The resulting class loader is defined
1875 * to be the system class loader. During construction, the class loader
1876 * should take great care to avoid calling {@code getSystemClassLoader()}.
1877 * If circular initialization of the system class loader is detected then
1878 * an {@code IllegalStateException} is thrown.
1879 *
1880 * @implNote The system property to override the system class loader is not
1881 * examined until the VM is almost fully initialized. Code that executes
1882 * this method during startup should take care not to cache the return
1883 * value until the system is fully initialized.
1884 *
1885 * <p> The name of the built-in system class loader is {@code "app"}.
1886 * The system property "{@code java.class.path}" is read during early
1887 * initialization of the VM to determine the class path.
1888 * An empty value of "{@code java.class.path}" property is interpreted
1889 * differently depending on whether the initial module (the module
1890 * containing the main class) is named or unnamed:
1891 * If named, the built-in system class loader will have no class path and
1892 * will search for classes and resources using the application module path;
1893 * otherwise, if unnamed, it will set the class path to the current
1894 * working directory.
1895 *
1896 * @return The system {@code ClassLoader}
1897 *
1898 * @throws SecurityException
1899 * If a security manager is present, and the caller's class loader
1900 * is not {@code null} and is not the same as or an ancestor of the
1901 * system class loader, and the caller does not have the
1902 * {@link RuntimePermission}{@code ("getClassLoader")}
1903 *
1904 * @throws IllegalStateException
1905 * If invoked recursively during the construction of the class
1906 * loader specified by the "{@code java.system.class.loader}"
1907 * property.
1908 *
1909 * @throws Error
1910 * If the system property "{@code java.system.class.loader}"
1911 * is defined but the named class could not be loaded, the
1912 * provider class does not define the required constructor, or an
1913 * exception is thrown by that constructor when it is invoked. The
1914 * underlying cause of the error can be retrieved via the
1915 * {@link Throwable#getCause()} method.
1916 *
1917 * @revised 1.4
1918 * @revised 9
1919 * @spec JPMS
1920 */
1921 @CallerSensitive
1922 public static ClassLoader getSystemClassLoader() {
1923 switch (VM.initLevel()) {
1924 case 0:
1925 case 1:
1926 case 2:
1927 // the system class loader is the built-in app class loader during startup
1928 return getBuiltinAppClassLoader();
1929 case 3:
1930 String msg = "getSystemClassLoader cannot be called during the system class loader instantiation";
1931 throw new IllegalStateException(msg);
1932 default:
1933 // system fully initialized
1934 assert VM.isBooted() && scl != null;
1935 SecurityManager sm = System.getSecurityManager();
1936 if (sm != null) {
1937 checkClassLoaderPermission(scl, Reflection.getCallerClass());
1938 }
1939 return scl;
1940 }
1941 }
1942
1943 static ClassLoader getBuiltinPlatformClassLoader() {
1944 return ClassLoaders.platformClassLoader();
1945 }
1946
1947 static ClassLoader getBuiltinAppClassLoader() {
1948 return ClassLoaders.appClassLoader();
1949 }
1950
1951 /*
1952 * Initialize the system class loader that may be a custom class on the
1953 * application class path or application module path.
1954 *
1955 * @see java.lang.System#initPhase3
1956 */
1957 static synchronized ClassLoader initSystemClassLoader() {
1958 if (VM.initLevel() != 3) {
1959 throw new InternalError("system class loader cannot be set at initLevel " +
1960 VM.initLevel());
1961 }
1962
1963 // detect recursive initialization
1964 if (scl != null) {
1965 throw new IllegalStateException("recursive invocation");
1966 }
1967
1968 ClassLoader builtinLoader = getBuiltinAppClassLoader();
1969
1970 // All are privileged frames. No need to call doPrivileged.
1971 String cn = System.getProperty("java.system.class.loader");
1972 if (cn != null) {
1973 try {
1974 // custom class loader is only supported to be loaded from unnamed module
1975 Constructor<?> ctor = Class.forName(cn, false, builtinLoader)
1976 .getDeclaredConstructor(ClassLoader.class);
1977 scl = (ClassLoader) ctor.newInstance(builtinLoader);
1978 } catch (Exception e) {
1979 Throwable cause = e;
1980 if (e instanceof InvocationTargetException) {
1981 cause = e.getCause();
1982 if (cause instanceof Error) {
1983 throw (Error) cause;
1984 }
1985 }
1986 if (cause instanceof RuntimeException) {
1987 throw (RuntimeException) cause;
1988 }
1989 throw new Error(cause.getMessage(), cause);
1990 }
1991 } else {
1992 scl = builtinLoader;
1993 }
1994 return scl;
1995 }
1996
1997 // Returns true if the specified class loader can be found in this class
1998 // loader's delegation chain.
1999 boolean isAncestor(ClassLoader cl) {
2000 ClassLoader acl = this;
2001 do {
2002 acl = acl.parent;
2003 if (cl == acl) {
2004 return true;
2005 }
2006 } while (acl != null);
2007 return false;
2008 }
2009
2010 // Tests if class loader access requires "getClassLoader" permission
2011 // check. A class loader 'from' can access class loader 'to' if
2012 // class loader 'from' is same as class loader 'to' or an ancestor
2013 // of 'to'. The class loader in a system domain can access
2014 // any class loader.
2015 private static boolean needsClassLoaderPermissionCheck(ClassLoader from,
2016 ClassLoader to)
2017 {
2018 if (from == to)
2019 return false;
2020
2021 if (from == null)
2022 return false;
2023
2024 return !to.isAncestor(from);
2025 }
2026
2027 // Returns the class's class loader, or null if none.
2028 static ClassLoader getClassLoader(Class<?> caller) {
2029 // This can be null if the VM is requesting it
2030 if (caller == null) {
2031 return null;
2032 }
2033 // Circumvent security check since this is package-private
2034 return caller.getClassLoader0();
2035 }
2036
2037 /*
2038 * Checks RuntimePermission("getClassLoader") permission
2039 * if caller's class loader is not null and caller's class loader
2040 * is not the same as or an ancestor of the given cl argument.
2041 */
2042 static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
2043 SecurityManager sm = System.getSecurityManager();
2044 if (sm != null) {
2045 // caller can be null if the VM is requesting it
2046 ClassLoader ccl = getClassLoader(caller);
2047 if (needsClassLoaderPermissionCheck(ccl, cl)) {
2048 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
2049 }
2050 }
2051 }
2052
2053 // The system class loader
2054 // @GuardedBy("ClassLoader.class")
2055 private static volatile ClassLoader scl;
2056
2057 // -- Package --
2058
2059 /**
2060 * Define a Package of the given Class object.
2061 *
2062 * If the given class represents an array type, a primitive type or void,
2063 * this method returns {@code null}.
2064 *
2065 * This method does not throw IllegalArgumentException.
2066 */
2067 Package definePackage(Class<?> c) {
2068 if (c.isPrimitive() || c.isArray()) {
2069 return null;
2070 }
2071
2072 return definePackage(c.getPackageName(), c.getModule());
2073 }
2074
2075 /**
2076 * Defines a Package of the given name and module
2077 *
2078 * This method does not throw IllegalArgumentException.
2079 *
2080 * @param name package name
2081 * @param m module
2082 */
2083 Package definePackage(String name, Module m) {
2084 if (name.isEmpty() && m.isNamed()) {
2085 throw new InternalError("unnamed package in " + m);
2086 }
2087
2088 // check if Package object is already defined
2089 NamedPackage pkg = packages.get(name);
2090 if (pkg instanceof Package)
2091 return (Package)pkg;
2092
2093 return (Package)packages.compute(name, (n, p) -> toPackage(n, p, m));
2094 }
2095
2096 /*
2097 * Returns a Package object for the named package
2098 */
2099 private Package toPackage(String name, NamedPackage p, Module m) {
2100 // define Package object if the named package is not yet defined
2101 if (p == null)
2102 return NamedPackage.toPackage(name, m);
2103
2104 // otherwise, replace the NamedPackage object with Package object
2105 if (p instanceof Package)
2106 return (Package)p;
2107
2108 return NamedPackage.toPackage(p.packageName(), p.module());
2109 }
2110
2111 /**
2112 * Defines a package by <a href="#binary-name">name</a> in this {@code ClassLoader}.
2113 * <p>
2114 * <a href="#binary-name">Package names</a> must be unique within a class loader and
2115 * cannot be redefined or changed once created.
2116 * <p>
2117 * If a class loader wishes to define a package with specific properties,
2118 * such as version information, then the class loader should call this
2119 * {@code definePackage} method before calling {@code defineClass}.
2120 * Otherwise, the
2121 * {@link #defineClass(String, byte[], int, int, ProtectionDomain) defineClass}
2122 * method will define a package in this class loader corresponding to the package
2123 * of the newly defined class; the properties of this defined package are
2124 * specified by {@link Package}.
2125 *
2126 * @apiNote
2127 * A class loader that wishes to define a package for classes in a JAR
2128 * typically uses the specification and implementation titles, versions, and
2129 * vendors from the JAR's manifest. If the package is specified as
2130 * {@linkplain java.util.jar.Attributes.Name#SEALED sealed} in the JAR's manifest,
2131 * the {@code URL} of the JAR file is typically used as the {@code sealBase}.
2132 * If classes of package {@code 'p'} defined by this class loader
2133 * are loaded from multiple JARs, the {@code Package} object may contain
2134 * different information depending on the first class of package {@code 'p'}
2135 * defined and which JAR's manifest is read first to explicitly define
2136 * package {@code 'p'}.
2137 *
2138 * <p> It is strongly recommended that a class loader does not call this
2139 * method to explicitly define packages in <em>named modules</em>; instead,
2140 * the package will be automatically defined when a class is {@linkplain
2141 * #defineClass(String, byte[], int, int, ProtectionDomain) being defined}.
2142 * If it is desirable to define {@code Package} explicitly, it should ensure
2143 * that all packages in a named module are defined with the properties
2144 * specified by {@link Package}. Otherwise, some {@code Package} objects
2145 * in a named module may be for example sealed with different seal base.
2146 *
2147 * @param name
2148 * The <a href="#binary-name">package name</a>
2149 *
2150 * @param specTitle
2151 * The specification title
2152 *
2153 * @param specVersion
2154 * The specification version
2155 *
2156 * @param specVendor
2157 * The specification vendor
2158 *
2159 * @param implTitle
2160 * The implementation title
2161 *
2162 * @param implVersion
2163 * The implementation version
2164 *
2165 * @param implVendor
2166 * The implementation vendor
2167 *
2168 * @param sealBase
2169 * If not {@code null}, then this package is sealed with
2170 * respect to the given code source {@link java.net.URL URL}
2171 * object. Otherwise, the package is not sealed.
2172 *
2173 * @return The newly defined {@code Package} object
2174 *
2175 * @throws NullPointerException
2176 * if {@code name} is {@code null}.
2177 *
2178 * @throws IllegalArgumentException
2179 * if a package of the given {@code name} is already
2180 * defined by this class loader
2181 *
2182 *
2183 * @since 1.2
2184 * @revised 9
2185 * @spec JPMS
2186 *
2187 * @jvms 5.3 Run-time package
2188 * @see <a href="{@docRoot}/../specs/jar/jar.html#package-sealing">
2189 * The JAR File Specification: Package Sealing</a>
2190 */
2191 protected Package definePackage(String name, String specTitle,
2192 String specVersion, String specVendor,
2193 String implTitle, String implVersion,
2194 String implVendor, URL sealBase)
2195 {
2196 Objects.requireNonNull(name);
2197
2198 // definePackage is not final and may be overridden by custom class loader
2199 Package p = new Package(name, specTitle, specVersion, specVendor,
2200 implTitle, implVersion, implVendor,
2201 sealBase, this);
2202
2203 if (packages.putIfAbsent(name, p) != null)
2204 throw new IllegalArgumentException(name);
2205
2206 return p;
2207 }
2208
2209 /**
2210 * Returns a {@code Package} of the given <a href="#binary-name">name</a> that
2211 * has been defined by this class loader.
2212 *
2213 * @param name The <a href="#binary-name">package name</a>
2214 *
2215 * @return The {@code Package} of the given name that has been defined
2216 * by this class loader, or {@code null} if not found
2217 *
2218 * @throws NullPointerException
2219 * if {@code name} is {@code null}.
2220 *
2221 * @jvms 5.3 Run-time package
2222 *
2223 * @since 9
2224 * @spec JPMS
2225 */
2226 public final Package getDefinedPackage(String name) {
2227 Objects.requireNonNull(name, "name cannot be null");
2228
2229 NamedPackage p = packages.get(name);
2230 if (p == null)
2231 return null;
2232
2233 return definePackage(name, p.module());
2234 }
2235
2236 /**
2237 * Returns all of the {@code Package}s that have been defined by
2238 * this class loader. The returned array has no duplicated {@code Package}s
2239 * of the same name.
2240 *
2241 * @apiNote This method returns an array rather than a {@code Set} or {@code Stream}
2242 * for consistency with the existing {@link #getPackages} method.
2243 *
2244 * @return The array of {@code Package} objects that have been defined by
2245 * this class loader; or an zero length array if no package has been
2246 * defined by this class loader.
2247 *
2248 * @jvms 5.3 Run-time package
2249 *
2250 * @since 9
2251 * @spec JPMS
2252 */
2253 public final Package[] getDefinedPackages() {
2254 return packages().toArray(Package[]::new);
2255 }
2256
2257 /**
2258 * Finds a package by <a href="#binary-name">name</a> in this class loader and its ancestors.
2259 * <p>
2260 * If this class loader defines a {@code Package} of the given name,
2261 * the {@code Package} is returned. Otherwise, the ancestors of
2262 * this class loader are searched recursively (parent by parent)
2263 * for a {@code Package} of the given name.
2264 *
2265 * @apiNote The {@link #getPlatformClassLoader() platform class loader}
2266 * may delegate to the application class loader but the application class
2267 * loader is not its ancestor. When invoked on the platform class loader,
2268 * this method will not find packages defined to the application
2269 * class loader.
2270 *
2271 * @param name
2272 * The <a href="#binary-name">package name</a>
2273 *
2274 * @return The {@code Package} of the given name that has been defined by
2275 * this class loader or its ancestors, or {@code null} if not found.
2276 *
2277 * @throws NullPointerException
2278 * if {@code name} is {@code null}.
2279 *
2280 * @deprecated
2281 * If multiple class loaders delegate to each other and define classes
2282 * with the same package name, and one such loader relies on the lookup
2283 * behavior of {@code getPackage} to return a {@code Package} from
2284 * a parent loader, then the properties exposed by the {@code Package}
2285 * may not be as expected in the rest of the program.
2286 * For example, the {@code Package} will only expose annotations from the
2287 * {@code package-info.class} file defined by the parent loader, even if
2288 * annotations exist in a {@code package-info.class} file defined by
2289 * a child loader. A more robust approach is to use the
2290 * {@link ClassLoader#getDefinedPackage} method which returns
2291 * a {@code Package} for the specified class loader.
2292 *
2293 * @see ClassLoader#getDefinedPackage(String)
2294 *
2295 * @since 1.2
2296 * @revised 9
2297 * @spec JPMS
2298 */
2299 @Deprecated(since="9")
2300 protected Package getPackage(String name) {
2301 Package pkg = getDefinedPackage(name);
2302 if (pkg == null) {
2303 if (parent != null) {
2304 pkg = parent.getPackage(name);
2305 } else {
2306 pkg = BootLoader.getDefinedPackage(name);
2307 }
2308 }
2309 return pkg;
2310 }
2311
2312 /**
2313 * Returns all of the {@code Package}s that have been defined by
2314 * this class loader and its ancestors. The returned array may contain
2315 * more than one {@code Package} object of the same package name, each
2316 * defined by a different class loader in the class loader hierarchy.
2317 *
2318 * @apiNote The {@link #getPlatformClassLoader() platform class loader}
2319 * may delegate to the application class loader. In other words,
2320 * packages in modules defined to the application class loader may be
2321 * visible to the platform class loader. On the other hand,
2322 * the application class loader is not its ancestor and hence
2323 * when invoked on the platform class loader, this method will not
2324 * return any packages defined to the application class loader.
2325 *
2326 * @return The array of {@code Package} objects that have been defined by
2327 * this class loader and its ancestors
2328 *
2329 * @see ClassLoader#getDefinedPackages()
2330 *
2331 * @since 1.2
2332 * @revised 9
2333 * @spec JPMS
2334 */
2335 protected Package[] getPackages() {
2336 Stream<Package> pkgs = packages();
2337 ClassLoader ld = parent;
2338 while (ld != null) {
2339 pkgs = Stream.concat(ld.packages(), pkgs);
2340 ld = ld.parent;
2341 }
2342 return Stream.concat(BootLoader.packages(), pkgs)
2343 .toArray(Package[]::new);
2344 }
2345
2346
2347
2348 // package-private
2349
2350 /**
2351 * Returns a stream of Packages defined in this class loader
2352 */
2353 Stream<Package> packages() {
2354 return packages.values().stream()
2355 .map(p -> definePackage(p.packageName(), p.module()));
2356 }
2357
2358 // -- Native library access --
2359
2360 /**
2361 * Returns the absolute path name of a native library. The VM invokes this
2362 * method to locate the native libraries that belong to classes loaded with
2363 * this class loader. If this method returns {@code null}, the VM
2364 * searches the library along the path specified as the
2365 * "{@code java.library.path}" property.
2366 *
2367 * @param libname
2368 * The library name
2369 *
2370 * @return The absolute path of the native library
2371 *
2372 * @see System#loadLibrary(String)
2373 * @see System#mapLibraryName(String)
2374 *
2375 * @since 1.2
2376 */
2377 protected String findLibrary(String libname) {
2378 return null;
2379 }
2380
2381 /**
2382 * The inner class NativeLibrary denotes a loaded native library instance.
2383 * Every classloader contains a vector of loaded native libraries in the
2384 * private field {@code nativeLibraries}. The native libraries loaded
2385 * into the system are entered into the {@code systemNativeLibraries}
2386 * vector.
2387 *
2388 * <p> Every native library requires a particular version of JNI. This is
2389 * denoted by the private {@code jniVersion} field. This field is set by
2390 * the VM when it loads the library, and used by the VM to pass the correct
2391 * version of JNI to the native methods. </p>
2392 *
2393 * @see ClassLoader
2394 * @since 1.2
2395 */
2396 static class NativeLibrary {
2397 // the class from which the library is loaded, also indicates
2398 // the loader this native library belongs.
2399 final Class<?> fromClass;
2400 // the canonicalized name of the native library.
2401 // or static library name
2402 final String name;
2403 // Indicates if the native library is linked into the VM
2404 final boolean isBuiltin;
2405
2406 // opaque handle to native library, used in native code.
2407 long handle;
2408 // the version of JNI environment the native library requires.
2409 int jniVersion;
2410
2411 native boolean load0(String name, boolean isBuiltin);
2412
2413 native long findEntry(String name);
2414
2415 NativeLibrary(Class<?> fromClass, String name, boolean isBuiltin) {
2416 this.name = name;
2417 this.fromClass = fromClass;
2418 this.isBuiltin = isBuiltin;
2419 }
2420
2421 /*
2422 * Loads the native library and registers for cleanup when its
2423 * associated class loader is unloaded
2424 */
2425 boolean load() {
2426 if (handle != 0) {
2427 throw new InternalError("Native library " + name + " has been loaded");
2428 }
2429
2430 if (!load0(name, isBuiltin)) return false;
2431
2432 // register the class loader for cleanup when unloaded
2433 // built class loaders are never unloaded
2434 ClassLoader loader = fromClass.getClassLoader();
2435 if (loader != null &&
2436 loader != getBuiltinPlatformClassLoader() &&
2437 loader != getBuiltinAppClassLoader()) {
2438 CleanerFactory.cleaner().register(loader,
2439 new Unloader(name, handle, isBuiltin));
2440 }
2441 return true;
2442 }
2443
2444 static boolean loadLibrary(Class<?> fromClass, String name, boolean isBuiltin) {
2445 ClassLoader loader =
2446 fromClass == null ? null : fromClass.getClassLoader();
2447
2448 synchronized (loadedLibraryNames) {
2449 Map<String, NativeLibrary> libs =
2450 loader != null ? loader.nativeLibraries() : systemNativeLibraries();
2451 if (libs.containsKey(name)) {
2452 return true;
2453 }
2454
2455 if (loadedLibraryNames.contains(name)) {
2456 throw new UnsatisfiedLinkError("Native Library " + name +
2457 " already loaded in another classloader");
2458 }
2459
2460 /*
2461 * When a library is being loaded, JNI_OnLoad function can cause
2462 * another loadLibrary invocation that should succeed.
2463 *
2464 * We use a static stack to hold the list of libraries we are
2465 * loading because this can happen only when called by the
2466 * same thread because Runtime.load and Runtime.loadLibrary
2467 * are synchronous.
2468 *
2469 * If there is a pending load operation for the library, we
2470 * immediately return success; otherwise, we raise
2471 * UnsatisfiedLinkError.
2472 */
2473 for (NativeLibrary lib : nativeLibraryContext) {
2474 if (name.equals(lib.name)) {
2475 if (loader == lib.fromClass.getClassLoader()) {
2476 return true;
2477 } else {
2478 throw new UnsatisfiedLinkError("Native Library " +
2479 name + " is being loaded in another classloader");
2480 }
2481 }
2482 }
2483 NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin);
2484 // load the native library
2485 nativeLibraryContext.push(lib);
2486 try {
2487 if (!lib.load()) return false;
2488 } finally {
2489 nativeLibraryContext.pop();
2490 }
2491 // register the loaded native library
2492 loadedLibraryNames.add(name);
2493 libs.put(name, lib);
2494 }
2495 return true;
2496 }
2497
2498 // Invoked in the VM to determine the context class in JNI_OnLoad
2499 // and JNI_OnUnload
2500 static Class<?> getFromClass() {
2501 return nativeLibraryContext.peek().fromClass;
2502 }
2503
2504 // native libraries being loaded
2505 static Deque<NativeLibrary> nativeLibraryContext = new ArrayDeque<>(8);
2506
2507 /*
2508 * The run() method will be invoked when this class loader becomes
2509 * phantom reachable to unload the native library.
2510 */
2511 static class Unloader implements Runnable {
2512 // This represents the context when a native library is unloaded
2513 // and getFromClass() will return null,
2514 static final NativeLibrary UNLOADER =
2515 new NativeLibrary(null, "dummy", false);
2516 final String name;
2517 final long handle;
2518 final boolean isBuiltin;
2519
2520 Unloader(String name, long handle, boolean isBuiltin) {
2521 if (handle == 0) {
2522 throw new IllegalArgumentException(
2523 "Invalid handle for native library " + name);
2524 }
2525
2526 this.name = name;
2527 this.handle = handle;
2528 this.isBuiltin = isBuiltin;
2529 }
2530
2531 @Override
2532 public void run() {
2533 synchronized (loadedLibraryNames) {
2534 /* remove the native library name */
2535 loadedLibraryNames.remove(name);
2536 nativeLibraryContext.push(UNLOADER);
2537 try {
2538 unload(name, isBuiltin, handle);
2539 } finally {
2540 nativeLibraryContext.pop();
2541 }
2542
2543 }
2544 }
2545 }
2546
2547 // JNI FindClass expects the caller class if invoked from JNI_OnLoad
2548 // and JNI_OnUnload is NativeLibrary class
2549 static native void unload(String name, boolean isBuiltin, long handle);
2550 }
2551
2552 // The paths searched for libraries
2553 private static String usr_paths[];
2554 private static String sys_paths[];
2555
2556 private static String[] initializePath(String propName) {
2557 String ldPath = System.getProperty(propName, "");
2558 int ldLen = ldPath.length();
2559 char ps = File.pathSeparatorChar;
2560 int psCount = 0;
2561
2562 if (ClassLoaderHelper.allowsQuotedPathElements &&
2563 ldPath.indexOf('\"') >= 0) {
2564 // First, remove quotes put around quoted parts of paths.
2565 // Second, use a quotation mark as a new path separator.
2566 // This will preserve any quoted old path separators.
2567 char[] buf = new char[ldLen];
2568 int bufLen = 0;
2569 for (int i = 0; i < ldLen; ++i) {
2570 char ch = ldPath.charAt(i);
2571 if (ch == '\"') {
2572 while (++i < ldLen &&
2573 (ch = ldPath.charAt(i)) != '\"') {
2574 buf[bufLen++] = ch;
2575 }
2576 } else {
2577 if (ch == ps) {
2578 psCount++;
2579 ch = '\"';
2580 }
2581 buf[bufLen++] = ch;
2582 }
2583 }
2584 ldPath = new String(buf, 0, bufLen);
2585 ldLen = bufLen;
2586 ps = '\"';
2587 } else {
2588 for (int i = ldPath.indexOf(ps); i >= 0;
2589 i = ldPath.indexOf(ps, i + 1)) {
2590 psCount++;
2591 }
2592 }
2593
2594 String[] paths = new String[psCount + 1];
2595 int pathStart = 0;
2596 for (int j = 0; j < psCount; ++j) {
2597 int pathEnd = ldPath.indexOf(ps, pathStart);
2598 paths[j] = (pathStart < pathEnd) ?
2599 ldPath.substring(pathStart, pathEnd) : ".";
2600 pathStart = pathEnd + 1;
2601 }
2602 paths[psCount] = (pathStart < ldLen) ?
2603 ldPath.substring(pathStart, ldLen) : ".";
2604 return paths;
2605 }
2606
2607 // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
2608 static void loadLibrary(Class<?> fromClass, String name,
2609 boolean isAbsolute) {
2610 ClassLoader loader =
2611 (fromClass == null) ? null : fromClass.getClassLoader();
2612 if (sys_paths == null) {
2613 usr_paths = initializePath("java.library.path");
2614 sys_paths = initializePath("sun.boot.library.path");
2615 }
2616 if (isAbsolute) {
2617 if (loadLibrary0(fromClass, new File(name))) {
2618 return;
2619 }
2620 throw new UnsatisfiedLinkError("Can't load library: " + name);
2621 }
2622 if (loader != null) {
2623 String libfilename = loader.findLibrary(name);
2624 if (libfilename != null) {
2625 File libfile = new File(libfilename);
2626 if (!libfile.isAbsolute()) {
2627 throw new UnsatisfiedLinkError(
2628 "ClassLoader.findLibrary failed to return an absolute path: " + libfilename);
2629 }
2630 if (loadLibrary0(fromClass, libfile)) {
2631 return;
2632 }
2633 throw new UnsatisfiedLinkError("Can't load " + libfilename);
2634 }
2635 }
2636 for (String sys_path : sys_paths) {
2637 File libfile = new File(sys_path, System.mapLibraryName(name));
2638 if (loadLibrary0(fromClass, libfile)) {
2639 return;
2640 }
2641 libfile = ClassLoaderHelper.mapAlternativeName(libfile);
2642 if (libfile != null && loadLibrary0(fromClass, libfile)) {
2643 return;
2644 }
2645 }
2646 if (loader != null) {
2647 for (String usr_path : usr_paths) {
2648 File libfile = new File(usr_path, System.mapLibraryName(name));
2649 if (loadLibrary0(fromClass, libfile)) {
2650 return;
2651 }
2652 libfile = ClassLoaderHelper.mapAlternativeName(libfile);
2653 if (libfile != null && loadLibrary0(fromClass, libfile)) {
2654 return;
2655 }
2656 }
2657 }
2658 // Oops, it failed
2659 throw new UnsatisfiedLinkError("no " + name +
2660 " in java.library.path: " + Arrays.toString(usr_paths));
2661 }
2662
2663 private static native String findBuiltinLib(String name);
2664
2665 private static boolean loadLibrary0(Class<?> fromClass, final File file) {
2666 // Check to see if we're attempting to access a static library
2667 String name = findBuiltinLib(file.getName());
2668 boolean isBuiltin = (name != null);
2669 if (!isBuiltin) {
2670 name = AccessController.doPrivileged(
2671 new PrivilegedAction<>() {
2672 public String run() {
2673 try {
2674 return file.exists() ? file.getCanonicalPath() : null;
2675 } catch (IOException e) {
2676 return null;
2677 }
2678 }
2679 });
2680 if (name == null) {
2681 return false;
2682 }
2683 }
2684 return NativeLibrary.loadLibrary(fromClass, name, isBuiltin);
2685 }
2686
2687 /*
2688 * Invoked in the VM class linking code.
2689 */
2690 private static long findNative(ClassLoader loader, String entryName) {
2691 Map<String, NativeLibrary> libs =
2692 loader != null ? loader.nativeLibraries() : systemNativeLibraries();
2693 if (libs.isEmpty())
2694 return 0;
2695
2696 // the native libraries map may be updated in another thread
2697 // when a native library is being loaded. No symbol will be
2698 // searched from it yet.
2699 for (NativeLibrary lib : libs.values()) {
2700 long entry = lib.findEntry(entryName);
2701 if (entry != 0) return entry;
2702 }
2703 return 0;
2704 }
2705
2706 // All native library names we've loaded.
2707 // This also serves as the lock to obtain nativeLibraries
2708 // and write to nativeLibraryContext.
2709 private static final Set<String> loadedLibraryNames = new HashSet<>();
2710
2711 // Native libraries belonging to system classes.
2712 private static volatile Map<String, NativeLibrary> systemNativeLibraries;
2713
2714 // Native libraries associated with the class loader.
2715 private volatile Map<String, NativeLibrary> nativeLibraries;
2716
2717 /*
2718 * Returns the native libraries map associated with bootstrap class loader
2719 * This method will create the map at the first time when called.
2720 */
2721 private static Map<String, NativeLibrary> systemNativeLibraries() {
2722 Map<String, NativeLibrary> libs = systemNativeLibraries;
2723 if (libs == null) {
2724 synchronized (loadedLibraryNames) {
2725 libs = systemNativeLibraries;
2726 if (libs == null) {
2727 libs = systemNativeLibraries = new ConcurrentHashMap<>();
2728 }
2729 }
2730 }
2731 return libs;
2732 }
2733
2734 /*
2735 * Returns the native libraries map associated with this class loader
2736 * This method will create the map at the first time when called.
2737 */
2738 private Map<String, NativeLibrary> nativeLibraries() {
2739 Map<String, NativeLibrary> libs = nativeLibraries;
2740 if (libs == null) {
2741 synchronized (loadedLibraryNames) {
2742 libs = nativeLibraries;
2743 if (libs == null) {
2744 libs = nativeLibraries = new ConcurrentHashMap<>();
2745 }
2746 }
2747 }
2748 return libs;
2749 }
2750
2751 // -- Assertion management --
2752
2753 final Object assertionLock;
2754
2755 // The default toggle for assertion checking.
2756 // @GuardedBy("assertionLock")
2757 private boolean defaultAssertionStatus = false;
2758
2759 // Maps String packageName to Boolean package default assertion status Note
2760 // that the default package is placed under a null map key. If this field
2761 // is null then we are delegating assertion status queries to the VM, i.e.,
2762 // none of this ClassLoader's assertion status modification methods have
2763 // been invoked.
2764 // @GuardedBy("assertionLock")
2765 private Map<String, Boolean> packageAssertionStatus = null;
2766
2767 // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
2768 // field is null then we are delegating assertion status queries to the VM,
2769 // i.e., none of this ClassLoader's assertion status modification methods
2770 // have been invoked.
2771 // @GuardedBy("assertionLock")
2772 Map<String, Boolean> classAssertionStatus = null;
2773
2774 /**
2775 * Sets the default assertion status for this class loader. This setting
2776 * determines whether classes loaded by this class loader and initialized
2777 * in the future will have assertions enabled or disabled by default.
2778 * This setting may be overridden on a per-package or per-class basis by
2779 * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
2780 * #setClassAssertionStatus(String, boolean)}.
2781 *
2782 * @param enabled
2783 * {@code true} if classes loaded by this class loader will
2784 * henceforth have assertions enabled by default, {@code false}
2785 * if they will have assertions disabled by default.
2786 *
2787 * @since 1.4
2788 */
2789 public void setDefaultAssertionStatus(boolean enabled) {
2790 synchronized (assertionLock) {
2791 if (classAssertionStatus == null)
2792 initializeJavaAssertionMaps();
2793
2794 defaultAssertionStatus = enabled;
2795 }
2796 }
2797
2798 /**
2799 * Sets the package default assertion status for the named package. The
2800 * package default assertion status determines the assertion status for
2801 * classes initialized in the future that belong to the named package or
2802 * any of its "subpackages".
2803 *
2804 * <p> A subpackage of a package named p is any package whose name begins
2805 * with "{@code p.}". For example, {@code javax.swing.text} is a
2806 * subpackage of {@code javax.swing}, and both {@code java.util} and
2807 * {@code java.lang.reflect} are subpackages of {@code java}.
2808 *
2809 * <p> In the event that multiple package defaults apply to a given class,
2810 * the package default pertaining to the most specific package takes
2811 * precedence over the others. For example, if {@code javax.lang} and
2812 * {@code javax.lang.reflect} both have package defaults associated with
2813 * them, the latter package default applies to classes in
2814 * {@code javax.lang.reflect}.
2815 *
2816 * <p> Package defaults take precedence over the class loader's default
2817 * assertion status, and may be overridden on a per-class basis by invoking
2818 * {@link #setClassAssertionStatus(String, boolean)}. </p>
2819 *
2820 * @param packageName
2821 * The name of the package whose package default assertion status
2822 * is to be set. A {@code null} value indicates the unnamed
2823 * package that is "current"
2824 * (see section 7.4.2 of
2825 * <cite>The Java™ Language Specification</cite>.)
2826 *
2827 * @param enabled
2828 * {@code true} if classes loaded by this classloader and
2829 * belonging to the named package or any of its subpackages will
2830 * have assertions enabled by default, {@code false} if they will
2831 * have assertions disabled by default.
2832 *
2833 * @since 1.4
2834 */
2835 public void setPackageAssertionStatus(String packageName,
2836 boolean enabled) {
2837 synchronized (assertionLock) {
2838 if (packageAssertionStatus == null)
2839 initializeJavaAssertionMaps();
2840
2841 packageAssertionStatus.put(packageName, enabled);
2842 }
2843 }
2844
2845 /**
2846 * Sets the desired assertion status for the named top-level class in this
2847 * class loader and any nested classes contained therein. This setting
2848 * takes precedence over the class loader's default assertion status, and
2849 * over any applicable per-package default. This method has no effect if
2850 * the named class has already been initialized. (Once a class is
2851 * initialized, its assertion status cannot change.)
2852 *
2853 * <p> If the named class is not a top-level class, this invocation will
2854 * have no effect on the actual assertion status of any class. </p>
2855 *
2856 * @param className
2857 * The fully qualified class name of the top-level class whose
2858 * assertion status is to be set.
2859 *
2860 * @param enabled
2861 * {@code true} if the named class is to have assertions
2862 * enabled when (and if) it is initialized, {@code false} if the
2863 * class is to have assertions disabled.
2864 *
2865 * @since 1.4
2866 */
2867 public void setClassAssertionStatus(String className, boolean enabled) {
2868 synchronized (assertionLock) {
2869 if (classAssertionStatus == null)
2870 initializeJavaAssertionMaps();
2871
2872 classAssertionStatus.put(className, enabled);
2873 }
2874 }
2875
2876 /**
2877 * Sets the default assertion status for this class loader to
2878 * {@code false} and discards any package defaults or class assertion
2879 * status settings associated with the class loader. This method is
2880 * provided so that class loaders can be made to ignore any command line or
2881 * persistent assertion status settings and "start with a clean slate."
2882 *
2883 * @since 1.4
2884 */
2885 public void clearAssertionStatus() {
2886 /*
2887 * Whether or not "Java assertion maps" are initialized, set
2888 * them to empty maps, effectively ignoring any present settings.
2889 */
2890 synchronized (assertionLock) {
2891 classAssertionStatus = new HashMap<>();
2892 packageAssertionStatus = new HashMap<>();
2893 defaultAssertionStatus = false;
2894 }
2895 }
2896
2897 /**
2898 * Returns the assertion status that would be assigned to the specified
2899 * class if it were to be initialized at the time this method is invoked.
2900 * If the named class has had its assertion status set, the most recent
2901 * setting will be returned; otherwise, if any package default assertion
2902 * status pertains to this class, the most recent setting for the most
2903 * specific pertinent package default assertion status is returned;
2904 * otherwise, this class loader's default assertion status is returned.
2905 * </p>
2906 *
2907 * @param className
2908 * The fully qualified class name of the class whose desired
2909 * assertion status is being queried.
2910 *
2911 * @return The desired assertion status of the specified class.
2912 *
2913 * @see #setClassAssertionStatus(String, boolean)
2914 * @see #setPackageAssertionStatus(String, boolean)
2915 * @see #setDefaultAssertionStatus(boolean)
2916 *
2917 * @since 1.4
2918 */
2919 boolean desiredAssertionStatus(String className) {
2920 synchronized (assertionLock) {
2921 // assert classAssertionStatus != null;
2922 // assert packageAssertionStatus != null;
2923
2924 // Check for a class entry
2925 Boolean result = classAssertionStatus.get(className);
2926 if (result != null)
2927 return result.booleanValue();
2928
2929 // Check for most specific package entry
2930 int dotIndex = className.lastIndexOf('.');
2931 if (dotIndex < 0) { // default package
2932 result = packageAssertionStatus.get(null);
2933 if (result != null)
2934 return result.booleanValue();
2935 }
2936 while(dotIndex > 0) {
2937 className = className.substring(0, dotIndex);
2938 result = packageAssertionStatus.get(className);
2939 if (result != null)
2940 return result.booleanValue();
2941 dotIndex = className.lastIndexOf('.', dotIndex-1);
2942 }
2943
2944 // Return the classloader default
2945 return defaultAssertionStatus;
2946 }
2947 }
2948
2949 // Set up the assertions with information provided by the VM.
2950 // Note: Should only be called inside a synchronized block
2951 private void initializeJavaAssertionMaps() {
2952 // assert Thread.holdsLock(assertionLock);
2953
2954 classAssertionStatus = new HashMap<>();
2955 packageAssertionStatus = new HashMap<>();
2956 AssertionStatusDirectives directives = retrieveDirectives();
2957
2958 for(int i = 0; i < directives.classes.length; i++)
2959 classAssertionStatus.put(directives.classes[i],
2960 directives.classEnabled[i]);
2961
2962 for(int i = 0; i < directives.packages.length; i++)
2963 packageAssertionStatus.put(directives.packages[i],
2964 directives.packageEnabled[i]);
2965
2966 defaultAssertionStatus = directives.deflt;
2967 }
2968
2969 // Retrieves the assertion directives from the VM.
2970 private static native AssertionStatusDirectives retrieveDirectives();
2971
2972
2973 // -- Misc --
2974
2975 /**
2976 * Returns the ConcurrentHashMap used as a storage for ClassLoaderValue(s)
2977 * associated with this ClassLoader, creating it if it doesn't already exist.
2978 */
2979 ConcurrentHashMap<?, ?> createOrGetClassLoaderValueMap() {
2980 ConcurrentHashMap<?, ?> map = classLoaderValueMap;
2981 if (map == null) {
2982 map = new ConcurrentHashMap<>();
2983 boolean set = trySetObjectField("classLoaderValueMap", map);
2984 if (!set) {
2985 // beaten by someone else
2986 map = classLoaderValueMap;
2987 }
2988 }
2989 return map;
2990 }
2991
2992 // the storage for ClassLoaderValue(s) associated with this ClassLoader
2993 private volatile ConcurrentHashMap<?, ?> classLoaderValueMap;
2994
2995 /**
2996 * Attempts to atomically set a volatile field in this object. Returns
2997 * {@code true} if not beaten by another thread. Avoids the use of
2998 * AtomicReferenceFieldUpdater in this class.
2999 */
3000 private boolean trySetObjectField(String name, Object obj) {
3001 Unsafe unsafe = Unsafe.getUnsafe();
3002 Class<?> k = ClassLoader.class;
3003 long offset;
3004 offset = unsafe.objectFieldOffset(k, name);
3005 return unsafe.compareAndSetObject(this, offset, null, obj);
3006 }
3007 }
3008
3009 /*
3010 * A utility class that will enumerate over an array of enumerations.
3011 */
3012 final class CompoundEnumeration<E> implements Enumeration<E> {
3013 private final Enumeration<E>[] enums;
3014 private int index;
3015
3016 public CompoundEnumeration(Enumeration<E>[] enums) {
3017 this.enums = enums;
3018 }
3019
3020 private boolean next() {
3021 while (index < enums.length) {
3022 if (enums[index] != null && enums[index].hasMoreElements()) {
3023 return true;
3024 }
3025 index++;
3026 }
3027 return false;
3028 }
3029
3030 public boolean hasMoreElements() {
3031 return next();
3032 }
3033
3034 public E nextElement() {
3035 if (!next()) {
3036 throw new NoSuchElementException();
3037 }
3038 return enums[index].nextElement();
3039 }
3040 }
3041