42 import java.util.HashMap;
43 import java.util.Map;
44 import java.util.NoSuchElementException;
45 import java.util.Objects;
46 import java.util.Set;
47 import java.util.Spliterator;
48 import java.util.Spliterators;
49 import java.util.WeakHashMap;
50 import java.util.concurrent.ConcurrentHashMap;
51 import java.util.function.Supplier;
52 import java.util.stream.Stream;
53 import java.util.stream.StreamSupport;
54
55 import jdk.internal.access.SharedSecrets;
56 import jdk.internal.loader.BootLoader;
57 import jdk.internal.loader.BuiltinClassLoader;
58 import jdk.internal.loader.ClassLoaders;
59 import jdk.internal.loader.NativeLibrary;
60 import jdk.internal.loader.NativeLibraries;
61 import jdk.internal.perf.PerfCounter;
62 import jdk.internal.misc.Unsafe;
63 import jdk.internal.misc.VM;
64 import jdk.internal.reflect.CallerSensitive;
65 import jdk.internal.reflect.CallerSensitiveAdapter;
66 import jdk.internal.reflect.Reflection;
67 import jdk.internal.util.StaticProperty;
68
69 /**
70 * A class loader is an object that is responsible for loading classes. The
71 * class {@code ClassLoader} is an abstract class. Given the <a
72 * href="#binary-name">binary name</a> of a class, a class loader should attempt to
73 * locate or generate data that constitutes a definition for the class. A
74 * typical strategy is to transform the name into a file name and then read a
75 * "class file" of that name from a file system.
76 *
77 * <p> Every {@link java.lang.Class Class} object contains a {@link
78 * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
79 * it.
80 *
81 * <p> {@code Class} objects for array classes are not created by class
1841 * @throws Error
1842 * If the system property "{@code java.system.class.loader}"
1843 * is defined but the named class could not be loaded, the
1844 * provider class does not define the required constructor, or an
1845 * exception is thrown by that constructor when it is invoked. The
1846 * underlying cause of the error can be retrieved via the
1847 * {@link Throwable#getCause()} method.
1848 */
1849 public static ClassLoader getSystemClassLoader() {
1850 switch (VM.initLevel()) {
1851 case 0:
1852 case 1:
1853 case 2:
1854 // the system class loader is the built-in app class loader during startup
1855 return getBuiltinAppClassLoader();
1856 case 3:
1857 String msg = "getSystemClassLoader cannot be called during the system class loader instantiation";
1858 throw new IllegalStateException(msg);
1859 default:
1860 // system fully initialized
1861 assert VM.isBooted() && scl != null;
1862 return scl;
1863 }
1864 }
1865
1866 static ClassLoader getBuiltinPlatformClassLoader() {
1867 return ClassLoaders.platformClassLoader();
1868 }
1869
1870 static ClassLoader getBuiltinAppClassLoader() {
1871 return ClassLoaders.appClassLoader();
1872 }
1873
1874 /*
1875 * Initialize the system class loader that may be a custom class on the
1876 * application class path or application module path.
1877 *
1878 * @see java.lang.System#initPhase3
1879 */
1880 static synchronized ClassLoader initSystemClassLoader() {
1881 if (VM.initLevel() != 3) {
1882 throw new InternalError("system class loader cannot be set at initLevel " +
1883 VM.initLevel());
1884 }
1885
1886 // detect recursive initialization
1887 if (scl != null) {
1888 throw new IllegalStateException("recursive invocation");
1889 }
1890
1891 ClassLoader builtinLoader = getBuiltinAppClassLoader();
1892 String cn = System.getProperty("java.system.class.loader");
1893 if (cn != null) {
1894 try {
1895 // custom class loader is only supported to be loaded from unnamed module
1896 Constructor<?> ctor = Class.forName(cn, false, builtinLoader)
1897 .getDeclaredConstructor(ClassLoader.class);
1898 scl = (ClassLoader) ctor.newInstance(builtinLoader);
1899 } catch (Exception e) {
1900 Throwable cause = e;
1901 if (e instanceof InvocationTargetException) {
1902 cause = e.getCause();
1903 if (cause instanceof Error) {
1904 throw (Error) cause;
1905 }
1906 }
1907 if (cause instanceof RuntimeException) {
1908 throw (RuntimeException) cause;
1909 }
1910 throw new Error(cause.getMessage(), cause);
1911 }
1912 } else {
1913 scl = builtinLoader;
1914 }
1915 return scl;
1916 }
1917
1918 // Returns the class's class loader, or null if none.
1919 static ClassLoader getClassLoader(Class<?> caller) {
1920 // This can be null if the VM is requesting it
1921 if (caller == null) {
1922 return null;
1923 }
1924 // Circumvent security check since this is package-private
1925 return caller.getClassLoader0();
1926 }
1927
1928 // The system class loader
1929 // @GuardedBy("ClassLoader.class")
1930 private static volatile ClassLoader scl;
1931
1932 // -- Package --
1933
1934 /**
1935 * Define a Package of the given Class object.
1936 *
1937 * If the given class represents an array type, a primitive type or void,
1938 * this method returns {@code null}.
1939 *
1940 * This method does not throw IllegalArgumentException.
1941 */
1942 Package definePackage(Class<?> c) {
1943 if (c.isPrimitive() || c.isArray()) {
1944 return null;
1945 }
1946
1947 return definePackage(c.getPackageName(), c.getModule());
1948 }
1949
1950 /**
2585 // Extra safety: check the types
2586 Object current = unsafe.getReference(this, offset);
2587 if (current.getClass() != obj.getClass()) {
2588 throw new IllegalStateException("Wrong field type");
2589 }
2590
2591 unsafe.putReference(this, offset, obj);
2592 }
2593
2594 /**
2595 * Called only by the VM, during -Xshare:dump.
2596 *
2597 * @implNote This is done while the JVM is running in single-threaded mode,
2598 * and at the very end of Java bytecode execution. We know that no more classes
2599 * will be loaded and none of the fields modified by this method will be used again.
2600 */
2601 private void resetArchivedStates() {
2602 if (parallelLockMap != null) {
2603 reinitObjectField("parallelLockMap", new ConcurrentHashMap<>());
2604 }
2605 reinitObjectField("packages", new ConcurrentHashMap<>());
2606 reinitObjectField("package2certs", new ConcurrentHashMap<>());
2607 classes.clear();
2608 classes.trimToSize();
2609 classLoaderValueMap = null;
2610 }
2611 }
2612
2613 /*
2614 * A utility class that will enumerate over an array of enumerations.
2615 */
2616 final class CompoundEnumeration<E> implements Enumeration<E> {
2617 private final Enumeration<E>[] enums;
2618 private int index;
2619
2620 public CompoundEnumeration(Enumeration<E>[] enums) {
2621 this.enums = enums;
2622 }
2623
2624 private boolean next() {
2625 while (index < enums.length) {
2626 if (enums[index] != null && enums[index].hasMoreElements()) {
2627 return true;
2628 }
2629 index++;
|
42 import java.util.HashMap;
43 import java.util.Map;
44 import java.util.NoSuchElementException;
45 import java.util.Objects;
46 import java.util.Set;
47 import java.util.Spliterator;
48 import java.util.Spliterators;
49 import java.util.WeakHashMap;
50 import java.util.concurrent.ConcurrentHashMap;
51 import java.util.function.Supplier;
52 import java.util.stream.Stream;
53 import java.util.stream.StreamSupport;
54
55 import jdk.internal.access.SharedSecrets;
56 import jdk.internal.loader.BootLoader;
57 import jdk.internal.loader.BuiltinClassLoader;
58 import jdk.internal.loader.ClassLoaders;
59 import jdk.internal.loader.NativeLibrary;
60 import jdk.internal.loader.NativeLibraries;
61 import jdk.internal.perf.PerfCounter;
62 import jdk.internal.misc.CDS;
63 import jdk.internal.misc.Unsafe;
64 import jdk.internal.misc.VM;
65 import jdk.internal.reflect.CallerSensitive;
66 import jdk.internal.reflect.CallerSensitiveAdapter;
67 import jdk.internal.reflect.Reflection;
68 import jdk.internal.util.StaticProperty;
69
70 /**
71 * A class loader is an object that is responsible for loading classes. The
72 * class {@code ClassLoader} is an abstract class. Given the <a
73 * href="#binary-name">binary name</a> of a class, a class loader should attempt to
74 * locate or generate data that constitutes a definition for the class. A
75 * typical strategy is to transform the name into a file name and then read a
76 * "class file" of that name from a file system.
77 *
78 * <p> Every {@link java.lang.Class Class} object contains a {@link
79 * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
80 * it.
81 *
82 * <p> {@code Class} objects for array classes are not created by class
1842 * @throws Error
1843 * If the system property "{@code java.system.class.loader}"
1844 * is defined but the named class could not be loaded, the
1845 * provider class does not define the required constructor, or an
1846 * exception is thrown by that constructor when it is invoked. The
1847 * underlying cause of the error can be retrieved via the
1848 * {@link Throwable#getCause()} method.
1849 */
1850 public static ClassLoader getSystemClassLoader() {
1851 switch (VM.initLevel()) {
1852 case 0:
1853 case 1:
1854 case 2:
1855 // the system class loader is the built-in app class loader during startup
1856 return getBuiltinAppClassLoader();
1857 case 3:
1858 String msg = "getSystemClassLoader cannot be called during the system class loader instantiation";
1859 throw new IllegalStateException(msg);
1860 default:
1861 // system fully initialized
1862 assert VM.isBooted() && Holder.scl != null;
1863 return Holder.scl;
1864 }
1865 }
1866
1867 static ClassLoader getBuiltinPlatformClassLoader() {
1868 return ClassLoaders.platformClassLoader();
1869 }
1870
1871 static ClassLoader getBuiltinAppClassLoader() {
1872 return ClassLoaders.appClassLoader();
1873 }
1874
1875 /*
1876 * Initialize the system class loader that may be a custom class on the
1877 * application class path or application module path.
1878 *
1879 * @see java.lang.System#initPhase3
1880 */
1881 static synchronized ClassLoader initSystemClassLoader() {
1882 if (VM.initLevel() != 3) {
1883 throw new InternalError("system class loader cannot be set at initLevel " +
1884 VM.initLevel());
1885 }
1886
1887 // detect recursive initialization
1888 if (Holder.scl != null) {
1889 throw new IllegalStateException("recursive invocation");
1890 }
1891
1892 ClassLoader builtinLoader = getBuiltinAppClassLoader();
1893 String cn = System.getProperty("java.system.class.loader");
1894 if (cn != null) {
1895 try {
1896 // custom class loader is only supported to be loaded from unnamed module
1897 Constructor<?> ctor = Class.forName(cn, false, builtinLoader)
1898 .getDeclaredConstructor(ClassLoader.class);
1899 Holder.scl = (ClassLoader) ctor.newInstance(builtinLoader);
1900 } catch (Exception e) {
1901 Throwable cause = e;
1902 if (e instanceof InvocationTargetException) {
1903 cause = e.getCause();
1904 if (cause instanceof Error) {
1905 throw (Error) cause;
1906 }
1907 }
1908 if (cause instanceof RuntimeException) {
1909 throw (RuntimeException) cause;
1910 }
1911 throw new Error(cause.getMessage(), cause);
1912 }
1913 } else {
1914 Holder.scl = builtinLoader;
1915 }
1916 return Holder.scl;
1917 }
1918
1919 // Returns the class's class loader, or null if none.
1920 static ClassLoader getClassLoader(Class<?> caller) {
1921 // This can be null if the VM is requesting it
1922 if (caller == null) {
1923 return null;
1924 }
1925 // Circumvent security check since this is package-private
1926 return caller.getClassLoader0();
1927 }
1928
1929 // Holder has the field(s) that need to be initialized during JVM bootstrap even if
1930 // the outer is aot-initialized.
1931 private static class Holder {
1932 // The system class loader
1933 // @GuardedBy("ClassLoader.class")
1934 private static volatile ClassLoader scl;
1935 }
1936
1937 // -- Package --
1938
1939 /**
1940 * Define a Package of the given Class object.
1941 *
1942 * If the given class represents an array type, a primitive type or void,
1943 * this method returns {@code null}.
1944 *
1945 * This method does not throw IllegalArgumentException.
1946 */
1947 Package definePackage(Class<?> c) {
1948 if (c.isPrimitive() || c.isArray()) {
1949 return null;
1950 }
1951
1952 return definePackage(c.getPackageName(), c.getModule());
1953 }
1954
1955 /**
2590 // Extra safety: check the types
2591 Object current = unsafe.getReference(this, offset);
2592 if (current.getClass() != obj.getClass()) {
2593 throw new IllegalStateException("Wrong field type");
2594 }
2595
2596 unsafe.putReference(this, offset, obj);
2597 }
2598
2599 /**
2600 * Called only by the VM, during -Xshare:dump.
2601 *
2602 * @implNote This is done while the JVM is running in single-threaded mode,
2603 * and at the very end of Java bytecode execution. We know that no more classes
2604 * will be loaded and none of the fields modified by this method will be used again.
2605 */
2606 private void resetArchivedStates() {
2607 if (parallelLockMap != null) {
2608 reinitObjectField("parallelLockMap", new ConcurrentHashMap<>());
2609 }
2610
2611 if (CDS.isDumpingPackages()) {
2612 if (System.getProperty("cds.debug.archived.packages") != null) {
2613 for (Map.Entry<String, NamedPackage> entry : packages.entrySet()) {
2614 String key = entry.getKey();
2615 NamedPackage value = entry.getValue();
2616 System.out.println("Archiving " +
2617 (value instanceof Package ? "Package" : "NamedPackage") +
2618 " \"" + key + "\" for " + this);
2619 }
2620 }
2621 } else {
2622 reinitObjectField("packages", new ConcurrentHashMap<>());
2623 }
2624
2625 reinitObjectField("package2certs", new ConcurrentHashMap<>());
2626 classes.clear();
2627 classes.trimToSize();
2628 classLoaderValueMap = null;
2629 libraries.clear();
2630 }
2631 }
2632
2633 /*
2634 * A utility class that will enumerate over an array of enumerations.
2635 */
2636 final class CompoundEnumeration<E> implements Enumeration<E> {
2637 private final Enumeration<E>[] enums;
2638 private int index;
2639
2640 public CompoundEnumeration(Enumeration<E>[] enums) {
2641 this.enums = enums;
2642 }
2643
2644 private boolean next() {
2645 while (index < enums.length) {
2646 if (enums[index] != null && enums[index].hasMoreElements()) {
2647 return true;
2648 }
2649 index++;
|