22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang; 28 29 import java.io.InputStream; 30 import java.io.IOException; 31 import java.io.UncheckedIOException; 32 import java.io.File; 33 import java.lang.reflect.Constructor; 34 import java.lang.reflect.InvocationTargetException; 35 import java.net.URL; 36 import java.security.AccessController; 37 import java.security.AccessControlContext; 38 import java.security.CodeSource; 39 import java.security.PrivilegedAction; 40 import java.security.ProtectionDomain; 41 import java.security.cert.Certificate; 42 import java.util.ArrayDeque; 43 import java.util.ArrayList; 44 import java.util.Arrays; 45 import java.util.Collections; 46 import java.util.Deque; 47 import java.util.Enumeration; 48 import java.util.HashMap; 49 import java.util.HashSet; 50 import java.util.Map; 51 import java.util.NoSuchElementException; 52 import java.util.Objects; 53 import java.util.Set; 54 import java.util.Spliterator; 55 import java.util.Spliterators; 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 jdk.internal.util.StaticProperty; 72 import sun.reflect.misc.ReflectUtil; 73 import sun.security.util.SecurityConstants; 74 75 /** 76 * A class loader is an object that is responsible for loading classes. The 77 * class {@code ClassLoader} is an abstract class. Given the <a 78 * href="#binary-name">binary name</a> of a class, a class loader should attempt to 79 * locate or generate data that constitutes a definition for the class. A 80 * typical strategy is to transform the name into a file name and then read a 81 * "class file" of that name from a file system. 82 * 83 * <p> Every {@link java.lang.Class Class} object contains a {@link 84 * Class#getClassLoader() reference} to the {@code ClassLoader} that defined 85 * it. 86 * 87 * <p> {@code Class} objects for array classes are not created by class 88 * loaders, but are created automatically as required by the Java runtime. 2360 * Returns the absolute path name of a native library. The VM invokes this 2361 * method to locate the native libraries that belong to classes loaded with 2362 * this class loader. If this method returns {@code null}, the VM 2363 * searches the library along the path specified as the 2364 * "{@code java.library.path}" property. 2365 * 2366 * @param libname 2367 * The library name 2368 * 2369 * @return The absolute path of the native library 2370 * 2371 * @see System#loadLibrary(String) 2372 * @see System#mapLibraryName(String) 2373 * 2374 * @since 1.2 2375 */ 2376 protected String findLibrary(String libname) { 2377 return null; 2378 } 2379 2380 /** 2381 * The inner class NativeLibrary denotes a loaded native library instance. 2382 * Every classloader contains a vector of loaded native libraries in the 2383 * private field {@code nativeLibraries}. The native libraries loaded 2384 * into the system are entered into the {@code systemNativeLibraries} 2385 * vector. 2386 * 2387 * <p> Every native library requires a particular version of JNI. This is 2388 * denoted by the private {@code jniVersion} field. This field is set by 2389 * the VM when it loads the library, and used by the VM to pass the correct 2390 * version of JNI to the native methods. </p> 2391 * 2392 * @see ClassLoader 2393 * @since 1.2 2394 */ 2395 static class NativeLibrary { 2396 // the class from which the library is loaded, also indicates 2397 // the loader this native library belongs. 2398 final Class<?> fromClass; 2399 // the canonicalized name of the native library. 2400 // or static library name 2401 final String name; 2402 // Indicates if the native library is linked into the VM 2403 final boolean isBuiltin; 2404 2405 // opaque handle to native library, used in native code. 2406 long handle; 2407 // the version of JNI environment the native library requires. 2408 int jniVersion; 2409 2410 native boolean load0(String name, boolean isBuiltin); 2411 2412 native long findEntry(String name); 2413 2414 NativeLibrary(Class<?> fromClass, String name, boolean isBuiltin) { 2415 this.name = name; 2416 this.fromClass = fromClass; 2417 this.isBuiltin = isBuiltin; 2418 } 2419 2420 /* 2421 * Loads the native library and registers for cleanup when its 2422 * associated class loader is unloaded 2423 */ 2424 boolean load() { 2425 if (handle != 0) { 2426 throw new InternalError("Native library " + name + " has been loaded"); 2427 } 2428 2429 if (!load0(name, isBuiltin)) return false; 2430 2431 // register the class loader for cleanup when unloaded 2432 // builtin class loaders are never unloaded 2433 ClassLoader loader = fromClass.getClassLoader(); 2434 if (loader != null && 2435 loader != getBuiltinPlatformClassLoader() && 2436 loader != getBuiltinAppClassLoader()) { 2437 CleanerFactory.cleaner().register(loader, 2438 new Unloader(name, handle, isBuiltin)); 2439 } 2440 return true; 2441 } 2442 2443 static boolean loadLibrary(Class<?> fromClass, String name, boolean isBuiltin) { 2444 ClassLoader loader = 2445 fromClass == null ? null : fromClass.getClassLoader(); 2446 2447 synchronized (loadedLibraryNames) { 2448 Map<String, NativeLibrary> libs = 2449 loader != null ? loader.nativeLibraries() : systemNativeLibraries(); 2450 if (libs.containsKey(name)) { 2451 return true; 2452 } 2453 2454 if (loadedLibraryNames.contains(name)) { 2455 throw new UnsatisfiedLinkError("Native Library " + name + 2456 " already loaded in another classloader"); 2457 } 2458 2459 /* 2460 * When a library is being loaded, JNI_OnLoad function can cause 2461 * another loadLibrary invocation that should succeed. 2462 * 2463 * We use a static stack to hold the list of libraries we are 2464 * loading because this can happen only when called by the 2465 * same thread because this block is synchronous. 2466 * 2467 * If there is a pending load operation for the library, we 2468 * immediately return success; otherwise, we raise 2469 * UnsatisfiedLinkError. 2470 */ 2471 for (NativeLibrary lib : nativeLibraryContext) { 2472 if (name.equals(lib.name)) { 2473 if (loader == lib.fromClass.getClassLoader()) { 2474 return true; 2475 } else { 2476 throw new UnsatisfiedLinkError("Native Library " + 2477 name + " is being loaded in another classloader"); 2478 } 2479 } 2480 } 2481 NativeLibrary lib = new NativeLibrary(fromClass, name, isBuiltin); 2482 // load the native library 2483 nativeLibraryContext.push(lib); 2484 try { 2485 if (!lib.load()) return false; 2486 } finally { 2487 nativeLibraryContext.pop(); 2488 } 2489 // register the loaded native library 2490 loadedLibraryNames.add(name); 2491 libs.put(name, lib); 2492 } 2493 return true; 2494 } 2495 2496 // Invoked in the VM to determine the context class in JNI_OnLoad 2497 // and JNI_OnUnload 2498 static Class<?> getFromClass() { 2499 return nativeLibraryContext.peek().fromClass; 2500 } 2501 2502 // native libraries being loaded 2503 static Deque<NativeLibrary> nativeLibraryContext = new ArrayDeque<>(8); 2504 2505 /* 2506 * The run() method will be invoked when this class loader becomes 2507 * phantom reachable to unload the native library. 2508 */ 2509 static class Unloader implements Runnable { 2510 // This represents the context when a native library is unloaded 2511 // and getFromClass() will return null, 2512 static final NativeLibrary UNLOADER = 2513 new NativeLibrary(null, "dummy", false); 2514 final String name; 2515 final long handle; 2516 final boolean isBuiltin; 2517 2518 Unloader(String name, long handle, boolean isBuiltin) { 2519 if (handle == 0) { 2520 throw new IllegalArgumentException( 2521 "Invalid handle for native library " + name); 2522 } 2523 2524 this.name = name; 2525 this.handle = handle; 2526 this.isBuiltin = isBuiltin; 2527 } 2528 2529 @Override 2530 public void run() { 2531 synchronized (loadedLibraryNames) { 2532 /* remove the native library name */ 2533 loadedLibraryNames.remove(name); 2534 nativeLibraryContext.push(UNLOADER); 2535 try { 2536 unload(name, isBuiltin, handle); 2537 } finally { 2538 nativeLibraryContext.pop(); 2539 } 2540 2541 } 2542 } 2543 } 2544 2545 // JNI FindClass expects the caller class if invoked from JNI_OnLoad 2546 // and JNI_OnUnload is NativeLibrary class 2547 static native void unload(String name, boolean isBuiltin, long handle); 2548 } 2549 2550 /** 2551 * Holds system and user library paths derived from the 2552 * {@code java.library.path} and {@code sun.boot.library.path} system 2553 * properties. The system properties are eagerly read at bootstrap, then 2554 * lazily parsed on first use to avoid initialization ordering issues. 2555 */ 2556 private static class LibraryPaths { 2557 static final String[] USER = 2558 ClassLoaderHelper.parsePath(StaticProperty.javaLibraryPath()); 2559 static final String[] SYS = 2560 ClassLoaderHelper.parsePath(StaticProperty.sunBootLibraryPath()); 2561 } 2562 2563 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. 2564 static void loadLibrary(Class<?> fromClass, String name, 2565 boolean isAbsolute) { 2566 ClassLoader loader = 2567 (fromClass == null) ? null : fromClass.getClassLoader(); 2568 2569 if (isAbsolute) { 2570 if (loadLibrary0(fromClass, new File(name))) { 2571 return; 2572 } 2573 throw new UnsatisfiedLinkError("Can't load library: " + name); 2574 } 2575 if (loader != null) { 2576 String libfilename = loader.findLibrary(name); 2577 if (libfilename != null) { 2578 File libfile = new File(libfilename); 2579 if (!libfile.isAbsolute()) { 2580 throw new UnsatisfiedLinkError( 2581 "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); 2582 } 2583 if (loadLibrary0(fromClass, libfile)) { 2584 return; 2585 } 2586 throw new UnsatisfiedLinkError("Can't load " + libfilename); 2587 } 2588 } 2589 for (String sysPath : LibraryPaths.SYS) { 2590 File libfile = new File(sysPath, System.mapLibraryName(name)); 2591 if (loadLibrary0(fromClass, libfile)) { 2592 return; 2593 } 2594 libfile = ClassLoaderHelper.mapAlternativeName(libfile); 2595 if (libfile != null && loadLibrary0(fromClass, libfile)) { 2596 return; 2597 } 2598 } 2599 if (loader != null) { 2600 for (String userPath : LibraryPaths.USER) { 2601 File libfile = new File(userPath, System.mapLibraryName(name)); 2602 if (loadLibrary0(fromClass, libfile)) { 2603 return; 2604 } 2605 libfile = ClassLoaderHelper.mapAlternativeName(libfile); 2606 if (libfile != null && loadLibrary0(fromClass, libfile)) { 2607 return; 2608 } 2609 } 2610 } 2611 // Oops, it failed 2612 throw new UnsatisfiedLinkError("no " + name + 2613 " in java.library.path: " + Arrays.toString(LibraryPaths.USER)); 2614 } 2615 2616 private static native String findBuiltinLib(String name); 2617 2618 private static boolean loadLibrary0(Class<?> fromClass, final File file) { 2619 // Check to see if we're attempting to access a static library 2620 String name = findBuiltinLib(file.getName()); 2621 boolean isBuiltin = (name != null); 2622 if (!isBuiltin) { 2623 name = AccessController.doPrivileged( 2624 new PrivilegedAction<>() { 2625 public String run() { 2626 try { 2627 return file.exists() ? file.getCanonicalPath() : null; 2628 } catch (IOException e) { 2629 return null; 2630 } 2631 } 2632 }); 2633 if (name == null) { 2634 return false; 2635 } 2636 } 2637 return NativeLibrary.loadLibrary(fromClass, name, isBuiltin); 2638 } 2639 2640 /* 2641 * Invoked in the VM class linking code. 2642 */ 2643 private static long findNative(ClassLoader loader, String entryName) { 2644 Map<String, NativeLibrary> libs = 2645 loader != null ? loader.nativeLibraries() : systemNativeLibraries(); 2646 if (libs.isEmpty()) 2647 return 0; 2648 2649 // the native libraries map may be updated in another thread 2650 // when a native library is being loaded. No symbol will be 2651 // searched from it yet. 2652 for (NativeLibrary lib : libs.values()) { 2653 long entry = lib.findEntry(entryName); 2654 if (entry != 0) return entry; 2655 } 2656 return 0; 2657 } 2658 2659 // All native library names we've loaded. 2660 // This also serves as the lock to obtain nativeLibraries 2661 // and write to nativeLibraryContext. 2662 private static final Set<String> loadedLibraryNames = new HashSet<>(); 2663 2664 // Native libraries belonging to system classes. 2665 private static volatile Map<String, NativeLibrary> systemNativeLibraries; 2666 2667 // Native libraries associated with the class loader. 2668 private volatile Map<String, NativeLibrary> nativeLibraries; 2669 2670 /* 2671 * Returns the native libraries map associated with bootstrap class loader 2672 * This method will create the map at the first time when called. 2673 */ 2674 private static Map<String, NativeLibrary> systemNativeLibraries() { 2675 Map<String, NativeLibrary> libs = systemNativeLibraries; 2676 if (libs == null) { 2677 synchronized (loadedLibraryNames) { 2678 libs = systemNativeLibraries; 2679 if (libs == null) { 2680 libs = systemNativeLibraries = new ConcurrentHashMap<>(); 2681 } 2682 } 2683 } 2684 return libs; 2685 } 2686 2687 /* 2688 * Returns the native libraries map associated with this class loader 2689 * This method will create the map at the first time when called. 2690 */ 2691 private Map<String, NativeLibrary> nativeLibraries() { 2692 Map<String, NativeLibrary> libs = nativeLibraries; 2693 if (libs == null) { 2694 synchronized (loadedLibraryNames) { 2695 libs = nativeLibraries; 2696 if (libs == null) { 2697 libs = nativeLibraries = new ConcurrentHashMap<>(); 2698 } 2699 } 2700 } 2701 return libs; 2702 } 2703 2704 // -- Assertion management -- 2705 2706 final Object assertionLock; 2707 2708 // The default toggle for assertion checking. 2709 // @GuardedBy("assertionLock") 2710 private boolean defaultAssertionStatus = false; 2711 2712 // Maps String packageName to Boolean package default assertion status Note 2713 // that the default package is placed under a null map key. If this field 2714 // is null then we are delegating assertion status queries to the VM, i.e., 2715 // none of this ClassLoader's assertion status modification methods have 2716 // been invoked. 2717 // @GuardedBy("assertionLock") 2718 private Map<String, Boolean> packageAssertionStatus = null; 2719 2720 // Maps String fullyQualifiedClassName to Boolean assertionStatus If this 2721 // field is null then we are delegating assertion status queries to the VM, | 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang; 28 29 import java.io.InputStream; 30 import java.io.IOException; 31 import java.io.UncheckedIOException; 32 import java.io.File; 33 import java.lang.reflect.Constructor; 34 import java.lang.reflect.InvocationTargetException; 35 import java.net.URL; 36 import java.security.AccessController; 37 import java.security.AccessControlContext; 38 import java.security.CodeSource; 39 import java.security.PrivilegedAction; 40 import java.security.ProtectionDomain; 41 import java.security.cert.Certificate; 42 import java.util.ArrayList; 43 import java.util.Collections; 44 import java.util.Enumeration; 45 import java.util.HashMap; 46 import java.util.HashSet; 47 import java.util.Map; 48 import java.util.NoSuchElementException; 49 import java.util.Objects; 50 import java.util.Set; 51 import java.util.Spliterator; 52 import java.util.Spliterators; 53 import java.util.WeakHashMap; 54 import java.util.concurrent.ConcurrentHashMap; 55 import java.util.function.Supplier; 56 import java.util.stream.Stream; 57 import java.util.stream.StreamSupport; 58 59 import jdk.internal.loader.BootLoader; 60 import jdk.internal.loader.BuiltinClassLoader; 61 import jdk.internal.loader.ClassLoaders; 62 import jdk.internal.loader.NativeLibrary; 63 import jdk.internal.loader.NativeLibraries; 64 import jdk.internal.perf.PerfCounter; 65 import jdk.internal.misc.Unsafe; 66 import jdk.internal.misc.VM; 67 import jdk.internal.reflect.CallerSensitive; 68 import jdk.internal.reflect.Reflection; 69 import jdk.internal.util.StaticProperty; 70 import sun.reflect.misc.ReflectUtil; 71 import sun.security.util.SecurityConstants; 72 73 /** 74 * A class loader is an object that is responsible for loading classes. The 75 * class {@code ClassLoader} is an abstract class. Given the <a 76 * href="#binary-name">binary name</a> of a class, a class loader should attempt to 77 * locate or generate data that constitutes a definition for the class. A 78 * typical strategy is to transform the name into a file name and then read a 79 * "class file" of that name from a file system. 80 * 81 * <p> Every {@link java.lang.Class Class} object contains a {@link 82 * Class#getClassLoader() reference} to the {@code ClassLoader} that defined 83 * it. 84 * 85 * <p> {@code Class} objects for array classes are not created by class 86 * loaders, but are created automatically as required by the Java runtime. 2358 * Returns the absolute path name of a native library. The VM invokes this 2359 * method to locate the native libraries that belong to classes loaded with 2360 * this class loader. If this method returns {@code null}, the VM 2361 * searches the library along the path specified as the 2362 * "{@code java.library.path}" property. 2363 * 2364 * @param libname 2365 * The library name 2366 * 2367 * @return The absolute path of the native library 2368 * 2369 * @see System#loadLibrary(String) 2370 * @see System#mapLibraryName(String) 2371 * 2372 * @since 1.2 2373 */ 2374 protected String findLibrary(String libname) { 2375 return null; 2376 } 2377 2378 private final NativeLibraries libraries = new NativeLibraries(this); 2379 2380 // Invoked in the java.lang.Runtime class to implement load and loadLibrary. 2381 static NativeLibrary loadLibrary(Class<?> fromClass, File file) { 2382 ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); 2383 NativeLibraries libs = loader != null ? loader.libraries : BootLoader.getNativeLibraries(); 2384 NativeLibrary nl = libs.loadLibrary(fromClass, file); 2385 if (nl != null) { 2386 return nl; 2387 } 2388 throw new UnsatisfiedLinkError("Can't load library: " + file); 2389 } 2390 static NativeLibrary loadLibrary(Class<?> fromClass, String name) { 2391 ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); 2392 if (loader == null) { 2393 NativeLibrary nl = BootLoader.getNativeLibraries().loadLibrary(fromClass, name); 2394 if (nl != null) { 2395 return nl; 2396 } 2397 throw new UnsatisfiedLinkError("no " + name + 2398 " in system library path: " + StaticProperty.sunBootLibraryPath()); 2399 } 2400 2401 NativeLibraries libs = loader.libraries; 2402 // First load from the file returned from ClassLoader::findLibrary, if found. 2403 String libfilename = loader.findLibrary(name); 2404 if (libfilename != null) { 2405 File libfile = new File(libfilename); 2406 if (!libfile.isAbsolute()) { 2407 throw new UnsatisfiedLinkError( 2408 "ClassLoader.findLibrary failed to return an absolute path: " + libfilename); 2409 } 2410 NativeLibrary nl = libs.loadLibrary(fromClass, libfile); 2411 if (nl != null) { 2412 return nl; 2413 } 2414 throw new UnsatisfiedLinkError("Can't load " + libfilename); 2415 } 2416 // Then load from system library path and java library path 2417 NativeLibrary nl = libs.loadLibrary(fromClass, name); 2418 if (nl != null) { 2419 return nl; 2420 } 2421 2422 // Oops, it failed 2423 throw new UnsatisfiedLinkError("no " + name + 2424 " in java.library.path: " + StaticProperty.javaLibraryPath()); 2425 } 2426 2427 /* 2428 * Invoked in the VM class linking code. 2429 */ 2430 private static long findNative(ClassLoader loader, String entryName) { 2431 if (loader == null) { 2432 return BootLoader.getNativeLibraries().lookup(entryName); 2433 } else { 2434 return loader.libraries.lookup(entryName); 2435 } 2436 } 2437 2438 // -- Assertion management -- 2439 2440 final Object assertionLock; 2441 2442 // The default toggle for assertion checking. 2443 // @GuardedBy("assertionLock") 2444 private boolean defaultAssertionStatus = false; 2445 2446 // Maps String packageName to Boolean package default assertion status Note 2447 // that the default package is placed under a null map key. If this field 2448 // is null then we are delegating assertion status queries to the VM, i.e., 2449 // none of this ClassLoader's assertion status modification methods have 2450 // been invoked. 2451 // @GuardedBy("assertionLock") 2452 private Map<String, Boolean> packageAssertionStatus = null; 2453 2454 // Maps String fullyQualifiedClassName to Boolean assertionStatus If this 2455 // field is null then we are delegating assertion status queries to the VM, |