< prev index next >

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

Print this page




  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.net.URL;
  34 import java.security.AccessController;
  35 import java.security.AccessControlContext;
  36 import java.security.CodeSource;
  37 import java.security.PrivilegedAction;
  38 import java.security.ProtectionDomain;
  39 import java.security.cert.Certificate;

  40 import java.util.Collections;

  41 import java.util.Enumeration;
  42 import java.util.HashMap;

  43 import java.util.Hashtable;

  44 import java.util.Map;
  45 import java.util.NoSuchElementException;
  46 import java.util.Objects;
  47 import java.util.Set;
  48 import java.util.Spliterator;
  49 import java.util.Spliterators;
  50 import java.util.Stack;
  51 import java.util.Vector;
  52 import java.util.WeakHashMap;
  53 import java.util.concurrent.ConcurrentHashMap;
  54 import java.util.function.Supplier;
  55 import java.util.stream.Stream;
  56 import java.util.stream.StreamSupport;
  57 
  58 import jdk.internal.perf.PerfCounter;
  59 import jdk.internal.loader.BootLoader;
  60 import jdk.internal.loader.ClassLoaders;
  61 import jdk.internal.misc.SharedSecrets;
  62 import jdk.internal.misc.Unsafe;
  63 import jdk.internal.misc.VM;

  64 import jdk.internal.reflect.CallerSensitive;
  65 import jdk.internal.reflect.Reflection;
  66 import sun.reflect.misc.ReflectUtil;
  67 import sun.security.util.SecurityConstants;
  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="#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
  82  * loaders, but are created automatically as required by the Java runtime.
  83  * The class loader for an array class, as returned by {@link


2358     protected String findLibrary(String libname) {
2359         return null;
2360     }
2361 
2362     /**
2363      * The inner class NativeLibrary denotes a loaded native library instance.
2364      * Every classloader contains a vector of loaded native libraries in the
2365      * private field {@code nativeLibraries}.  The native libraries loaded
2366      * into the system are entered into the {@code systemNativeLibraries}
2367      * vector.
2368      *
2369      * <p> Every native library requires a particular version of JNI. This is
2370      * denoted by the private {@code jniVersion} field.  This field is set by
2371      * the VM when it loads the library, and used by the VM to pass the correct
2372      * version of JNI to the native methods.  </p>
2373      *
2374      * @see      ClassLoader
2375      * @since    1.2
2376      */
2377     static class NativeLibrary {
2378         // opaque handle to native library, used in native code.
2379         long handle;
2380         // the version of JNI environment the native library requires.
2381         private int jniVersion;
2382         // the class from which the library is loaded, also indicates
2383         // the loader this native library belongs.
2384         private final Class<?> fromClass;
2385         // the canonicalized name of the native library.
2386         // or static library name
2387         String name;
2388         // Indicates if the native library is linked into the VM
2389         boolean isBuiltin;
2390         // Indicates if the native library is loaded
2391         boolean loaded;
2392         native void load(String name, boolean isBuiltin);


2393 
2394         native long find(String name);
2395         native void unload(String name, boolean isBuiltin);
2396 
2397         public NativeLibrary(Class<?> fromClass, String name, boolean isBuiltin) {


2398             this.name = name;
2399             this.fromClass = fromClass;
2400             this.isBuiltin = isBuiltin;
2401         }
2402 
2403         @SuppressWarnings("deprecation")
2404         protected void finalize() {

























2405             synchronized (loadedLibraryNames) {
2406                 if (fromClass.getClassLoader() != null && loaded) {
2407                     /* remove the native library name */
2408                     int size = loadedLibraryNames.size();
2409                     for (int i = 0; i < size; i++) {
2410                         if (name.equals(loadedLibraryNames.elementAt(i))) {
2411                             loadedLibraryNames.removeElementAt(i);
2412                             break;
2413                         }




2414                     }
2415                     /* unload the library. */
2416                     ClassLoader.nativeLibraryContext.push(this);

























2417                     try {
2418                         unload(name, isBuiltin);
2419                     } finally {
2420                         ClassLoader.nativeLibraryContext.pop();
2421                     }
2422                 }



2423             }

2424         }
2425         // Invoked in the VM to determine the context class in
2426         // JNI_Load/JNI_Unload

2427         static Class<?> getFromClass() {
2428             return ClassLoader.nativeLibraryContext.peek().fromClass;
2429         }





















2430     }
2431 
2432     // All native library names we've loaded.
2433     private static Vector<String> loadedLibraryNames = new Vector<>();


2434 
2435     // Native libraries belonging to system classes.
2436     private static Vector<NativeLibrary> systemNativeLibraries
2437         = new Vector<>();








2438 
2439     // Native libraries associated with the class loader.
2440     private Vector<NativeLibrary> nativeLibraries = new Vector<>();

2441 
2442     // native libraries being loaded/unloaded.
2443     private static Stack<NativeLibrary> nativeLibraryContext = new Stack<>();


2444 
2445     // The paths searched for libraries
2446     private static String usr_paths[];
2447     private static String sys_paths[];
2448 
2449     private static String[] initializePath(String propName) {
2450         String ldPath = System.getProperty(propName, "");
2451         int ldLen = ldPath.length();
2452         char ps = File.pathSeparatorChar;
2453         int psCount = 0;
2454 
2455         if (ClassLoaderHelper.allowsQuotedPathElements &&
2456                 ldPath.indexOf('\"') >= 0) {
2457             // First, remove quotes put around quoted parts of paths.
2458             // Second, use a quotation mark as a new path separator.
2459             // This will preserve any quoted old path separators.
2460             char[] buf = new char[ldLen];
2461             int bufLen = 0;
2462             for (int i = 0; i < ldLen; ++i) {
2463                 char ch = ldPath.charAt(i);


2532                 return;
2533             }
2534             libfile = ClassLoaderHelper.mapAlternativeName(libfile);
2535             if (libfile != null && loadLibrary0(fromClass, libfile)) {
2536                 return;
2537             }
2538         }
2539         if (loader != null) {
2540             for (String usr_path : usr_paths) {
2541                 File libfile = new File(usr_path, System.mapLibraryName(name));
2542                 if (loadLibrary0(fromClass, libfile)) {
2543                     return;
2544                 }
2545                 libfile = ClassLoaderHelper.mapAlternativeName(libfile);
2546                 if (libfile != null && loadLibrary0(fromClass, libfile)) {
2547                     return;
2548                 }
2549             }
2550         }
2551         // Oops, it failed
2552         throw new UnsatisfiedLinkError("no " + name + " in java.library.path");

2553     }
2554 
2555     static native String findBuiltinLib(String name);
2556 
2557     private static boolean loadLibrary0(Class<?> fromClass, final File file) {
2558         // Check to see if we're attempting to access a static library
2559         String name = findBuiltinLib(file.getName());
2560         boolean isBuiltin = (name != null);
2561         if (!isBuiltin) {
2562             name = AccessController.doPrivileged(
2563                 new PrivilegedAction<>() {
2564                     public String run() {
2565                         try {
2566                             return file.exists() ? file.getCanonicalPath() : null;
2567                         } catch (IOException e) {
2568                             return null;
2569                         }
2570                     }
2571                 });
2572             if (name == null) {
2573                 return false;
2574             }
2575         }
2576         ClassLoader loader =
2577             (fromClass == null) ? null : fromClass.getClassLoader();
2578         Vector<NativeLibrary> libs =
2579             loader != null ? loader.nativeLibraries : systemNativeLibraries;
2580         synchronized (libs) {
2581             int size = libs.size();
2582             for (int i = 0; i < size; i++) {
2583                 NativeLibrary lib = libs.elementAt(i);
2584                 if (name.equals(lib.name)) {
2585                     return true;
2586                 }
2587             }
2588 
2589             synchronized (loadedLibraryNames) {
2590                 if (loadedLibraryNames.contains(name)) {
2591                     throw new UnsatisfiedLinkError
2592                         ("Native Library " +
2593                          name +
2594                          " already loaded in another classloader");
2595                 }
2596                 /* If the library is being loaded (must be by the same thread,
2597                  * because Runtime.load and Runtime.loadLibrary are
2598                  * synchronous). The reason is can occur is that the JNI_OnLoad
2599                  * function can cause another loadLibrary invocation.
2600                  *
2601                  * Thus we can use a static stack to hold the list of libraries
2602                  * we are loading.
2603                  *
2604                  * If there is a pending load operation for the library, we
2605                  * immediately return success; otherwise, we raise
2606                  * UnsatisfiedLinkError.
2607                  */
2608                 int n = nativeLibraryContext.size();
2609                 for (int i = 0; i < n; i++) {
2610                     NativeLibrary lib = nativeLibraryContext.elementAt(i);
2611                     if (name.equals(lib.name)) {
2612                         if (loader == lib.fromClass.getClassLoader()) {
2613                             return true;
2614                         } else {
2615                             throw new UnsatisfiedLinkError
2616                                 ("Native Library " +
2617                                  name +
2618                                  " is being loaded in another classloader");
2619                         }
2620                     }
2621                 }
2622                 NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin);
2623                 nativeLibraryContext.push(lib);
2624                 try {
2625                     lib.load(name, isBuiltin);
2626                 } finally {
2627                     nativeLibraryContext.pop();
2628                 }
2629                 if (lib.loaded) {
2630                     loadedLibraryNames.addElement(name);
2631                     libs.addElement(lib);
2632                     return true;



















2633                 }
2634                 return false;
2635             }
2636         }

2637     }
2638 
2639     // Invoked in the VM class linking code.
2640     static long findNative(ClassLoader loader, String name) {
2641         Vector<NativeLibrary> libs =
2642             loader != null ? loader.nativeLibraries : systemNativeLibraries;
2643         synchronized (libs) {
2644             int size = libs.size();
2645             for (int i = 0; i < size; i++) {
2646                 NativeLibrary lib = libs.elementAt(i);
2647                 long entry = lib.find(name);
2648                 if (entry != 0)
2649                     return entry;
2650             }
2651         }
2652         return 0;
2653     }
2654 

2655 
2656     // -- Assertion management --
2657 
2658     final Object assertionLock;
2659 
2660     // The default toggle for assertion checking.
2661     // @GuardedBy("assertionLock")
2662     private boolean defaultAssertionStatus = false;
2663 
2664     // Maps String packageName to Boolean package default assertion status Note
2665     // that the default package is placed under a null map key.  If this field
2666     // is null then we are delegating assertion status queries to the VM, i.e.,
2667     // none of this ClassLoader's assertion status modification methods have
2668     // been invoked.
2669     // @GuardedBy("assertionLock")
2670     private Map<String, Boolean> packageAssertionStatus = null;
2671 
2672     // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
2673     // field is null then we are delegating assertion status queries to the VM,
2674     // i.e., none of this ClassLoader's assertion status modification methods




  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.net.URL;
  34 import java.security.AccessController;
  35 import java.security.AccessControlContext;
  36 import java.security.CodeSource;
  37 import java.security.PrivilegedAction;
  38 import java.security.ProtectionDomain;
  39 import java.security.cert.Certificate;
  40 import java.util.Arrays;
  41 import java.util.Collections;
  42 import java.util.Deque;
  43 import java.util.Enumeration;
  44 import java.util.HashMap;
  45 import java.util.HashSet;
  46 import java.util.Hashtable;
  47 import java.util.LinkedList;
  48 import java.util.Map;
  49 import java.util.NoSuchElementException;
  50 import java.util.Objects;
  51 import java.util.Set;
  52 import java.util.Spliterator;
  53 import java.util.Spliterators;

  54 import java.util.Vector;
  55 import java.util.WeakHashMap;
  56 import java.util.concurrent.ConcurrentHashMap;
  57 import java.util.function.Supplier;
  58 import java.util.stream.Stream;
  59 import java.util.stream.StreamSupport;
  60 
  61 import jdk.internal.perf.PerfCounter;
  62 import jdk.internal.loader.BootLoader;
  63 import jdk.internal.loader.ClassLoaders;

  64 import jdk.internal.misc.Unsafe;
  65 import jdk.internal.misc.VM;
  66 import jdk.internal.ref.CleanerFactory;
  67 import jdk.internal.reflect.CallerSensitive;
  68 import jdk.internal.reflect.Reflection;
  69 import sun.reflect.misc.ReflectUtil;
  70 import sun.security.util.SecurityConstants;
  71 
  72 /**
  73  * A class loader is an object that is responsible for loading classes. The
  74  * class {@code ClassLoader} is an abstract class.  Given the <a
  75  * href="#name">binary name</a> of a class, a class loader should attempt to
  76  * locate or generate data that constitutes a definition for the class.  A
  77  * typical strategy is to transform the name into a file name and then read a
  78  * "class file" of that name from a file system.
  79  *
  80  * <p> Every {@link java.lang.Class Class} object contains a {@link
  81  * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
  82  * it.
  83  *
  84  * <p> {@code Class} objects for array classes are not created by class
  85  * loaders, but are created automatically as required by the Java runtime.
  86  * The class loader for an array class, as returned by {@link


2361     protected String findLibrary(String libname) {
2362         return null;
2363     }
2364 
2365     /**
2366      * The inner class NativeLibrary denotes a loaded native library instance.
2367      * Every classloader contains a vector of loaded native libraries in the
2368      * private field {@code nativeLibraries}.  The native libraries loaded
2369      * into the system are entered into the {@code systemNativeLibraries}
2370      * vector.
2371      *
2372      * <p> Every native library requires a particular version of JNI. This is
2373      * denoted by the private {@code jniVersion} field.  This field is set by
2374      * the VM when it loads the library, and used by the VM to pass the correct
2375      * version of JNI to the native methods.  </p>
2376      *
2377      * @see      ClassLoader
2378      * @since    1.2
2379      */
2380     static class NativeLibrary {




2381         // the class from which the library is loaded, also indicates
2382         // the loader this native library belongs.
2383         final Class<?> fromClass;
2384         // the canonicalized name of the native library.
2385         // or static library name
2386         final String name;
2387         // Indicates if the native library is linked into the VM
2388         final boolean isBuiltin;
2389 
2390         // opaque handle to native library, used in native code.
2391         long handle;
2392         // the version of JNI environment the native library requires.
2393         int jniVersion;
2394 
2395         native boolean load0(String name, boolean isBuiltin);

2396 
2397         native long findEntry(String name);
2398 
2399         NativeLibrary(Class<?> fromClass, String name, boolean isBuiltin) {
2400             this.name = name;
2401             this.fromClass = fromClass;
2402             this.isBuiltin = isBuiltin;
2403         }
2404 
2405         /*
2406          * Loads the native library and registers for cleanup when its
2407          * associated class loader is unloaded
2408          */
2409         boolean load() {
2410             if (handle != 0) {
2411                 throw new InternalError("Native library " + name + " has been loaded");
2412             }
2413 
2414             if (!load0(name, isBuiltin)) return false;
2415 
2416             // register the class loader for cleanup when unloaded
2417             // built class loaders are never unloaded
2418             ClassLoader loader = fromClass.getClassLoader();
2419             if (loader != null &&
2420                 loader != getBuiltinPlatformClassLoader() &&
2421                 loader != getBuiltinAppClassLoader()) {
2422                 CleanerFactory.cleaner().register(loader,
2423                         new Unloader(name, handle, isBuiltin));
2424             }
2425             return true;
2426         }
2427 
2428         static boolean loadLibrary(Class<?> fromClass, String name, boolean isBuiltin) {
2429             ClassLoader loader =
2430                 fromClass == null ? null : fromClass.getClassLoader();
2431 
2432             synchronized (loadedLibraryNames) {
2433                 Map<String, NativeLibrary> libs =
2434                     loader != null ? loader.nativeLibraries() : systemNativeLibraries();
2435                 if (libs.containsKey(name)) {
2436                     return true;



2437                 }
2438 
2439                 if (loadedLibraryNames.contains(name)) {
2440                     throw new UnsatisfiedLinkError("Native Library " + name +
2441                         " already loaded in another classloader");
2442                 }
2443 
2444                 /*
2445                  * When a library is being loaded, JNI_OnLoad function can cause
2446                  * another loadLibrary invocation that should succeed.
2447                  *
2448                  * We use a static stack to hold the list of libraries we are
2449                  * loading because this can happen only when called by the
2450                  * same thread because Runtime.load and Runtime.loadLibrary
2451                  * are synchronous.
2452                  *
2453                  * If there is a pending load operation for the library, we
2454                  * immediately return success; otherwise, we raise
2455                  * UnsatisfiedLinkError.
2456                  */
2457                 for (NativeLibrary lib : nativeLibraryContext) {
2458                     if (name.equals(lib.name)) {
2459                         if (loader == lib.fromClass.getClassLoader()) {
2460                             return true;
2461                         } else {
2462                             throw new UnsatisfiedLinkError("Native Library " +
2463                                 name + " is being loaded in another classloader");
2464                         }
2465                     }
2466                 }
2467                 NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin);
2468                 // load the native library
2469                 nativeLibraryContext.push(lib);
2470                 try {
2471                     if (!lib.load()) return false;
2472                 } finally {
2473                     nativeLibraryContext.pop();

2474                 }
2475                 // register the loaded native library
2476                 loadedLibraryNames.add(name);
2477                 libs.put(name, lib);
2478             }
2479             return true;
2480         }
2481 
2482         // Invoked in the VM to determine the context class in JNI_OnLoad
2483         // and JNI_OnUnload
2484         static Class<?> getFromClass() {
2485             return nativeLibraryContext.peek().fromClass;
2486         }
2487 
2488         // native libraries being loaded
2489         static Deque<NativeLibrary> nativeLibraryContext = new LinkedList<>();
2490 
2491         /*
2492          * The run() method will be invoked when this class loader becomes
2493          * phantom reachable to unload the native library.
2494          */
2495         static class Unloader implements Runnable {
2496             // This represents the context when a native library is unloaded
2497             // and getFromClass() will return null,
2498             static final NativeLibrary UNLOADER =
2499                 new NativeLibrary(null, "dummy", false);
2500             final String name;
2501             final long handle;
2502             final boolean isBuiltin;
2503 
2504             Unloader(String name, long handle, boolean isBuiltin) {
2505                 if (handle == 0) {
2506                     throw new IllegalArgumentException(
2507                         "Invalid handle for native library " + name);
2508                 }
2509 
2510                 this.name = name;
2511                 this.handle = handle;
2512                 this.isBuiltin = isBuiltin;
2513             }
2514 
2515             @Override
2516             public void run() {
2517                 synchronized (loadedLibraryNames) {
2518                     /* remove the native library name */
2519                     loadedLibraryNames.remove(name);
2520                     nativeLibraryContext.push(UNLOADER);
2521                     try {
2522                         unload(name, isBuiltin, handle);
2523                     } finally {
2524                         nativeLibraryContext.pop();
2525                     }
2526 
2527                 }
2528             }
2529         }
2530 
2531         // JNI FindClass expects the caller class if invoked from JNI_OnLoad
2532         // and JNI_OnUnload is NativeLibrary class
2533         static native void unload(String name, boolean isBuiltin, long handle);
2534     }
2535 
2536     // The paths searched for libraries
2537     private static String usr_paths[];
2538     private static String sys_paths[];
2539 
2540     private static String[] initializePath(String propName) {
2541         String ldPath = System.getProperty(propName, "");
2542         int ldLen = ldPath.length();
2543         char ps = File.pathSeparatorChar;
2544         int psCount = 0;
2545 
2546         if (ClassLoaderHelper.allowsQuotedPathElements &&
2547             ldPath.indexOf('\"') >= 0) {
2548             // First, remove quotes put around quoted parts of paths.
2549             // Second, use a quotation mark as a new path separator.
2550             // This will preserve any quoted old path separators.
2551             char[] buf = new char[ldLen];
2552             int bufLen = 0;
2553             for (int i = 0; i < ldLen; ++i) {
2554                 char ch = ldPath.charAt(i);


2623                 return;
2624             }
2625             libfile = ClassLoaderHelper.mapAlternativeName(libfile);
2626             if (libfile != null && loadLibrary0(fromClass, libfile)) {
2627                 return;
2628             }
2629         }
2630         if (loader != null) {
2631             for (String usr_path : usr_paths) {
2632                 File libfile = new File(usr_path, System.mapLibraryName(name));
2633                 if (loadLibrary0(fromClass, libfile)) {
2634                     return;
2635                 }
2636                 libfile = ClassLoaderHelper.mapAlternativeName(libfile);
2637                 if (libfile != null && loadLibrary0(fromClass, libfile)) {
2638                     return;
2639                 }
2640             }
2641         }
2642         // Oops, it failed
2643         throw new UnsatisfiedLinkError("no " + name +
2644             " in java.library.path: " + Arrays.toString(usr_paths));
2645     }
2646 
2647     private static native String findBuiltinLib(String name);
2648 
2649     private static boolean loadLibrary0(Class<?> fromClass, final File file) {
2650         // Check to see if we're attempting to access a static library
2651         String name = findBuiltinLib(file.getName());
2652         boolean isBuiltin = (name != null);
2653         if (!isBuiltin) {
2654             name = AccessController.doPrivileged(
2655                 new PrivilegedAction<>() {
2656                     public String run() {
2657                         try {
2658                             return file.exists() ? file.getCanonicalPath() : null;
2659                         } catch (IOException e) {
2660                             return null;
2661                         }
2662                     }
2663                 });
2664             if (name == null) {
2665                 return false;
2666             }
2667         }
2668         return NativeLibrary.loadLibrary(fromClass, name, isBuiltin);










2669     }
2670 
2671     /*
2672      * Invoked in the VM class linking code.
















2673      */
2674     private static long findNative(ClassLoader loader, String name) {
2675         Map<String, NativeLibrary> libs =
2676             loader != null ? loader.nativeLibraries() : systemNativeLibraries();
2677         if (libs.isEmpty())
2678             return 0;
2679 
2680         // the native libraries map may be updated in another thread
2681         // when a native library is being loaded.  No symbol will be
2682         // searched from it yet.
2683         for (NativeLibrary lib : libs.values()) {
2684             long entry = lib.findEntry(name);
2685             if (entry != 0) return entry;

2686         }
2687         return 0;





2688     }
2689 
2690     // All native library names we've loaded.
2691     // This also serves as the lock to obtain nativeLibraries
2692     // and write to nativeLibraryContext.
2693     private static final Set<String> loadedLibraryNames = new HashSet<>();
2694 
2695     // Native libraries belonging to system classes.
2696     private static volatile Map<String, NativeLibrary> systemNativeLibraries;
2697 
2698     // Native libraries associated with the class loader.
2699     private volatile Map<String, NativeLibrary> nativeLibraries;
2700 
2701     /*
2702      * Returns the native libraries map associated with bootstrap class loader
2703      * This method will create the map at the first time when called.
2704      */
2705     private static Map<String, NativeLibrary> systemNativeLibraries() {
2706         Map<String, NativeLibrary> libs = systemNativeLibraries;
2707         if (libs == null) {
2708             synchronized (loadedLibraryNames) {
2709                 libs = systemNativeLibraries;
2710                 if (libs == null) {
2711                     libs = systemNativeLibraries = new ConcurrentHashMap<>();
2712                 }

2713             }
2714         }
2715         return libs;
2716     }
2717 
2718     /*
2719      * Returns the native libraries map associated with this class loader
2720      * This method will create the map at the first time when called.
2721      */
2722     private Map<String, NativeLibrary> nativeLibraries() {
2723         Map<String, NativeLibrary> libs = nativeLibraries;
2724         if (libs == null) {
2725             synchronized (loadedLibraryNames) {
2726                 libs = nativeLibraries;
2727                 if (libs == null) {
2728                     libs = nativeLibraries = new ConcurrentHashMap<>();
2729                 }
2730             }

2731         }
2732         return libs;
2733     }
2734 
2735     // -- Assertion management --
2736 
2737     final Object assertionLock;
2738 
2739     // The default toggle for assertion checking.
2740     // @GuardedBy("assertionLock")
2741     private boolean defaultAssertionStatus = false;
2742 
2743     // Maps String packageName to Boolean package default assertion status Note
2744     // that the default package is placed under a null map key.  If this field
2745     // is null then we are delegating assertion status queries to the VM, i.e.,
2746     // none of this ClassLoader's assertion status modification methods have
2747     // been invoked.
2748     // @GuardedBy("assertionLock")
2749     private Map<String, Boolean> packageAssertionStatus = null;
2750 
2751     // Maps String fullyQualifiedClassName to Boolean assertionStatus If this
2752     // field is null then we are delegating assertion status queries to the VM,
2753     // i.e., none of this ClassLoader's assertion status modification methods


< prev index next >