< prev index next >

src/java.base/share/classes/java/lang/ClassLoader.java

Print this page

  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++;
< prev index next >