< prev index next >

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

Print this page

   1 /*
   2  * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

  41 import java.util.Enumeration;
  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.loader.BootLoader;
  56 import jdk.internal.loader.BuiltinClassLoader;
  57 import jdk.internal.loader.ClassLoaders;
  58 import jdk.internal.loader.NativeLibrary;
  59 import jdk.internal.loader.NativeLibraries;
  60 import jdk.internal.perf.PerfCounter;

  61 import jdk.internal.misc.Unsafe;
  62 import jdk.internal.misc.VM;
  63 import jdk.internal.reflect.CallerSensitive;
  64 import jdk.internal.reflect.CallerSensitiveAdapter;
  65 import jdk.internal.reflect.Reflection;
  66 import jdk.internal.util.StaticProperty;
  67 
  68 /**
  69  * A class loader is an object that is responsible for loading classes. The
  70  * class {@code ClassLoader} is an abstract class.  Given the <a
  71  * href="#binary-name">binary name</a> of a class, a class loader should attempt to
  72  * locate or generate data that constitutes a definition for the class.  A
  73  * typical strategy is to transform the name into a file name and then read a
  74  * "class file" of that name from a file system.
  75  *
  76  * <p> Every {@link java.lang.Class Class} object contains a {@link
  77  * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
  78  * it.
  79  *
  80  * <p> {@code Class} objects for array classes are not created by class

1832      * @throws  Error
1833      *          If the system property "{@code java.system.class.loader}"
1834      *          is defined but the named class could not be loaded, the
1835      *          provider class does not define the required constructor, or an
1836      *          exception is thrown by that constructor when it is invoked. The
1837      *          underlying cause of the error can be retrieved via the
1838      *          {@link Throwable#getCause()} method.
1839      */
1840     public static ClassLoader getSystemClassLoader() {
1841         switch (VM.initLevel()) {
1842             case 0:
1843             case 1:
1844             case 2:
1845                 // the system class loader is the built-in app class loader during startup
1846                 return getBuiltinAppClassLoader();
1847             case 3:
1848                 String msg = "getSystemClassLoader cannot be called during the system class loader instantiation";
1849                 throw new IllegalStateException(msg);
1850             default:
1851                 // system fully initialized
1852                 assert VM.isBooted() && scl != null;
1853                 return scl;
1854         }
1855     }
1856 
1857     static ClassLoader getBuiltinPlatformClassLoader() {
1858         return ClassLoaders.platformClassLoader();
1859     }
1860 
1861     static ClassLoader getBuiltinAppClassLoader() {
1862         return ClassLoaders.appClassLoader();
1863     }
1864 
1865     /*
1866      * Initialize the system class loader that may be a custom class on the
1867      * application class path or application module path.
1868      *
1869      * @see java.lang.System#initPhase3
1870      */
1871     static synchronized ClassLoader initSystemClassLoader() {
1872         if (VM.initLevel() != 3) {
1873             throw new InternalError("system class loader cannot be set at initLevel " +
1874                                     VM.initLevel());
1875         }
1876 
1877         // detect recursive initialization
1878         if (scl != null) {
1879             throw new IllegalStateException("recursive invocation");
1880         }
1881 
1882         ClassLoader builtinLoader = getBuiltinAppClassLoader();
1883         String cn = System.getProperty("java.system.class.loader");
1884         if (cn != null) {
1885             try {
1886                 // custom class loader is only supported to be loaded from unnamed module
1887                 Constructor<?> ctor = Class.forName(cn, false, builtinLoader)
1888                                            .getDeclaredConstructor(ClassLoader.class);
1889                 scl = (ClassLoader) ctor.newInstance(builtinLoader);
1890             } catch (Exception e) {
1891                 Throwable cause = e;
1892                 if (e instanceof InvocationTargetException) {
1893                     cause = e.getCause();
1894                     if (cause instanceof Error) {
1895                         throw (Error) cause;
1896                     }
1897                 }
1898                 if (cause instanceof RuntimeException) {
1899                     throw (RuntimeException) cause;
1900                 }
1901                 throw new Error(cause.getMessage(), cause);
1902             }
1903         } else {
1904             scl = builtinLoader;
1905         }
1906         return scl;
1907     }
1908 
1909     // Returns the class's class loader, or null if none.
1910     static ClassLoader getClassLoader(Class<?> caller) {
1911         // This can be null if the VM is requesting it
1912         if (caller == null) {
1913             return null;
1914         }
1915         // Circumvent security check since this is package-private
1916         return caller.getClassLoader0();
1917     }
1918 
1919     // The system class loader
1920     // @GuardedBy("ClassLoader.class")
1921     private static volatile ClassLoader scl;




1922 
1923     // -- Package --
1924 
1925     /**
1926      * Define a Package of the given Class object.
1927      *
1928      * If the given class represents an array type, a primitive type or void,
1929      * this method returns {@code null}.
1930      *
1931      * This method does not throw IllegalArgumentException.
1932      */
1933     Package definePackage(Class<?> c) {
1934         if (c.isPrimitive() || c.isArray()) {
1935             return null;
1936         }
1937 
1938         return definePackage(c.getPackageName(), c.getModule());
1939     }
1940 
1941     /**

2561     /**
2562      * Attempts to atomically set a volatile field in this object. Returns
2563      * {@code true} if not beaten by another thread. Avoids the use of
2564      * AtomicReferenceFieldUpdater in this class.
2565      */
2566     private boolean trySetObjectField(String name, Object obj) {
2567         Unsafe unsafe = Unsafe.getUnsafe();
2568         Class<?> k = ClassLoader.class;
2569         long offset;
2570         offset = unsafe.objectFieldOffset(k, name);
2571         return unsafe.compareAndSetReference(this, offset, null, obj);
2572     }
2573 
2574     /**
2575      * Called by the VM, during -Xshare:dump
2576      */
2577     private void resetArchivedStates() {
2578         if (parallelLockMap != null) {
2579             parallelLockMap.clear();
2580         }
2581         packages.clear();
2582         package2certs.clear();













2583         classes.clear();
2584         classLoaderValueMap = null;

2585     }
2586 }
2587 
2588 /*
2589  * A utility class that will enumerate over an array of enumerations.
2590  */
2591 final class CompoundEnumeration<E> implements Enumeration<E> {
2592     private final Enumeration<E>[] enums;
2593     private int index;
2594 
2595     public CompoundEnumeration(Enumeration<E>[] enums) {
2596         this.enums = enums;
2597     }
2598 
2599     private boolean next() {
2600         while (index < enums.length) {
2601             if (enums[index] != null && enums[index].hasMoreElements()) {
2602                 return true;
2603             }
2604             index++;

   1 /*
   2  * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.  Oracle designates this
   9  * particular file as subject to the "Classpath" exception as provided
  10  * by Oracle in the LICENSE file that accompanied this code.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA

  41 import java.util.Enumeration;
  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.loader.BootLoader;
  56 import jdk.internal.loader.BuiltinClassLoader;
  57 import jdk.internal.loader.ClassLoaders;
  58 import jdk.internal.loader.NativeLibrary;
  59 import jdk.internal.loader.NativeLibraries;
  60 import jdk.internal.perf.PerfCounter;
  61 import jdk.internal.misc.CDS;
  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

1833      * @throws  Error
1834      *          If the system property "{@code java.system.class.loader}"
1835      *          is defined but the named class could not be loaded, the
1836      *          provider class does not define the required constructor, or an
1837      *          exception is thrown by that constructor when it is invoked. The
1838      *          underlying cause of the error can be retrieved via the
1839      *          {@link Throwable#getCause()} method.
1840      */
1841     public static ClassLoader getSystemClassLoader() {
1842         switch (VM.initLevel()) {
1843             case 0:
1844             case 1:
1845             case 2:
1846                 // the system class loader is the built-in app class loader during startup
1847                 return getBuiltinAppClassLoader();
1848             case 3:
1849                 String msg = "getSystemClassLoader cannot be called during the system class loader instantiation";
1850                 throw new IllegalStateException(msg);
1851             default:
1852                 // system fully initialized
1853                 assert VM.isBooted() && Holder.scl != null;
1854                 return Holder.scl;
1855         }
1856     }
1857 
1858     static ClassLoader getBuiltinPlatformClassLoader() {
1859         return ClassLoaders.platformClassLoader();
1860     }
1861 
1862     static ClassLoader getBuiltinAppClassLoader() {
1863         return ClassLoaders.appClassLoader();
1864     }
1865 
1866     /*
1867      * Initialize the system class loader that may be a custom class on the
1868      * application class path or application module path.
1869      *
1870      * @see java.lang.System#initPhase3
1871      */
1872     static synchronized ClassLoader initSystemClassLoader() {
1873         if (VM.initLevel() != 3) {
1874             throw new InternalError("system class loader cannot be set at initLevel " +
1875                                     VM.initLevel());
1876         }
1877 
1878         // detect recursive initialization
1879         if (Holder.scl != null) {
1880             throw new IllegalStateException("recursive invocation");
1881         }
1882 
1883         ClassLoader builtinLoader = getBuiltinAppClassLoader();
1884         String cn = System.getProperty("java.system.class.loader");
1885         if (cn != null) {
1886             try {
1887                 // custom class loader is only supported to be loaded from unnamed module
1888                 Constructor<?> ctor = Class.forName(cn, false, builtinLoader)
1889                                            .getDeclaredConstructor(ClassLoader.class);
1890                 Holder.scl = (ClassLoader) ctor.newInstance(builtinLoader);
1891             } catch (Exception e) {
1892                 Throwable cause = e;
1893                 if (e instanceof InvocationTargetException) {
1894                     cause = e.getCause();
1895                     if (cause instanceof Error) {
1896                         throw (Error) cause;
1897                     }
1898                 }
1899                 if (cause instanceof RuntimeException) {
1900                     throw (RuntimeException) cause;
1901                 }
1902                 throw new Error(cause.getMessage(), cause);
1903             }
1904         } else {
1905             Holder.scl = builtinLoader;
1906         }
1907         return Holder.scl;
1908     }
1909 
1910     // Returns the class's class loader, or null if none.
1911     static ClassLoader getClassLoader(Class<?> caller) {
1912         // This can be null if the VM is requesting it
1913         if (caller == null) {
1914             return null;
1915         }
1916         // Circumvent security check since this is package-private
1917         return caller.getClassLoader0();
1918     }
1919 
1920     // Holder has the field(s) that need to be initialized during JVM bootstrap even if
1921     // the outer is aot-initialized.
1922     private static class Holder {
1923         // The system class loader
1924         // @GuardedBy("ClassLoader.class")
1925         private static volatile ClassLoader scl;
1926     }
1927 
1928     // -- Package --
1929 
1930     /**
1931      * Define a Package of the given Class object.
1932      *
1933      * If the given class represents an array type, a primitive type or void,
1934      * this method returns {@code null}.
1935      *
1936      * This method does not throw IllegalArgumentException.
1937      */
1938     Package definePackage(Class<?> c) {
1939         if (c.isPrimitive() || c.isArray()) {
1940             return null;
1941         }
1942 
1943         return definePackage(c.getPackageName(), c.getModule());
1944     }
1945 
1946     /**

2566     /**
2567      * Attempts to atomically set a volatile field in this object. Returns
2568      * {@code true} if not beaten by another thread. Avoids the use of
2569      * AtomicReferenceFieldUpdater in this class.
2570      */
2571     private boolean trySetObjectField(String name, Object obj) {
2572         Unsafe unsafe = Unsafe.getUnsafe();
2573         Class<?> k = ClassLoader.class;
2574         long offset;
2575         offset = unsafe.objectFieldOffset(k, name);
2576         return unsafe.compareAndSetReference(this, offset, null, obj);
2577     }
2578 
2579     /**
2580      * Called by the VM, during -Xshare:dump
2581      */
2582     private void resetArchivedStates() {
2583         if (parallelLockMap != null) {
2584             parallelLockMap.clear();
2585         }
2586 
2587         if (CDS.isDumpingPackages()) {
2588             if (System.getProperty("cds.debug.archived.packages") != null) {
2589                 for (Map.Entry<String, NamedPackage> entry : packages.entrySet()) {
2590                     String key = entry.getKey();
2591                     NamedPackage value = entry.getValue();
2592                     System.out.println("Archiving " + 
2593                                        (value instanceof Package ? "Package" : "NamedPackage") +
2594                                        " \"" + key + "\" for " + this);
2595                 }
2596             }
2597         } else {
2598             packages.clear();
2599             package2certs.clear();
2600         }
2601         classes.clear();
2602         classLoaderValueMap = null;
2603         libraries.clear();
2604     }
2605 }
2606 
2607 /*
2608  * A utility class that will enumerate over an array of enumerations.
2609  */
2610 final class CompoundEnumeration<E> implements Enumeration<E> {
2611     private final Enumeration<E>[] enums;
2612     private int index;
2613 
2614     public CompoundEnumeration(Enumeration<E>[] enums) {
2615         this.enums = enums;
2616     }
2617 
2618     private boolean next() {
2619         while (index < enums.length) {
2620             if (enums[index] != null && enums[index].hasMoreElements()) {
2621                 return true;
2622             }
2623             index++;
< prev index next >