/*
 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.internal.loader;

import java.io.IOException;
import java.net.URL;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.util.jar.Manifest;

import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.misc.VM;

Creates and provides access to the built-in platform and application class loaders. It also creates the class loader that is used to locate resources in modules defined to the boot class loader.
/** * Creates and provides access to the built-in platform and application class * loaders. It also creates the class loader that is used to locate resources * in modules defined to the boot class loader. */
public class ClassLoaders { private ClassLoaders() { } private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); // the built-in class loaders private static final BootClassLoader BOOT_LOADER; private static final PlatformClassLoader PLATFORM_LOADER; private static final AppClassLoader APP_LOADER; // Creates the built-in class loaders. static { // -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute String append = VM.getSavedProperty("jdk.boot.class.path.append"); BOOT_LOADER = new BootClassLoader((append != null && !append.isEmpty()) ? new URLClassPath(append, true) : null); PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER); // A class path is required when no initial module is specified. // In this case the class path defaults to "", meaning the current // working directory. When an initial module is specified, on the // contrary, we drop this historic interpretation of the empty // string and instead treat it as unspecified. String cp = System.getProperty("java.class.path"); if (cp == null || cp.isEmpty()) { String initialModuleName = System.getProperty("jdk.module.main"); cp = (initialModuleName == null) ? "" : null; } URLClassPath ucp = new URLClassPath(cp, false); APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp); }
Returns the class loader that is used to find resources in modules defined to the boot class loader.
API Note:This method is not public, it should instead be used via the BootLoader class that provides a restricted API to this class loader.
/** * Returns the class loader that is used to find resources in modules * defined to the boot class loader. * * @apiNote This method is not public, it should instead be used via * the BootLoader class that provides a restricted API to this class * loader. */
static BuiltinClassLoader bootLoader() { return BOOT_LOADER; }
Returns the platform class loader.
/** * Returns the platform class loader. */
public static ClassLoader platformClassLoader() { return PLATFORM_LOADER; }
Returns the application class loader.
/** * Returns the application class loader. */
public static ClassLoader appClassLoader() { return APP_LOADER; }
The class loader that is used to find resources in modules defined to the boot class loader. It is not used for class loading.
/** * The class loader that is used to find resources in modules defined to * the boot class loader. It is not used for class loading. */
private static class BootClassLoader extends BuiltinClassLoader { BootClassLoader(URLClassPath bcp) { super(null, null, bcp); } @Override protected Class<?> loadClassOrNull(String cn) { return JLA.findBootstrapClassOrNull(this, cn); } };
The platform class loader, a unique type to make it easier to distinguish from the application class loader.
/** * The platform class loader, a unique type to make it easier to distinguish * from the application class loader. */
private static class PlatformClassLoader extends BuiltinClassLoader { static { if (!ClassLoader.registerAsParallelCapable()) throw new InternalError(); } PlatformClassLoader(BootClassLoader parent) { super("platform", parent, null); }
Called by the VM to support define package for AppCDS. Shared classes are returned in ClassLoader::findLoadedClass that bypass the defineClass call.
/** * Called by the VM to support define package for AppCDS. * * Shared classes are returned in ClassLoader::findLoadedClass * that bypass the defineClass call. */
private Package definePackage(String pn, Module module) { return JLA.definePackage(this, pn, module); } }
The application class loader that is a BuiltinClassLoader with customizations to be compatible with long standing behavior.
/** * The application class loader that is a {@code BuiltinClassLoader} with * customizations to be compatible with long standing behavior. */
private static class AppClassLoader extends BuiltinClassLoader { static { if (!ClassLoader.registerAsParallelCapable()) throw new InternalError(); } final URLClassPath ucp; AppClassLoader(PlatformClassLoader parent, URLClassPath ucp) { super("app", parent, ucp); this.ucp = ucp; } @Override protected Class<?> loadClass(String cn, boolean resolve) throws ClassNotFoundException { // for compatibility reasons, say where restricted package list has // been updated to list API packages in the unnamed module. SecurityManager sm = System.getSecurityManager(); if (sm != null) { int i = cn.lastIndexOf('.'); if (i != -1) { sm.checkPackageAccess(cn.substring(0, i)); } } return super.loadClass(cn, resolve); } @Override protected PermissionCollection getPermissions(CodeSource cs) { PermissionCollection perms = super.getPermissions(cs); perms.add(new RuntimePermission("exitVM")); return perms; }
Called by the VM to support dynamic additions to the class path
See Also:
  • appendToSystemClassLoaderSearch.appendToSystemClassLoaderSearch
/** * Called by the VM to support dynamic additions to the class path * * @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch */
void appendToClassPathForInstrumentation(String path) { ucp.addFile(path); }
Called by the VM to support define package for AppCDS Shared classes are returned in ClassLoader::findLoadedClass that bypass the defineClass call.
/** * Called by the VM to support define package for AppCDS * * Shared classes are returned in ClassLoader::findLoadedClass * that bypass the defineClass call. */
private Package definePackage(String pn, Module module) { return JLA.definePackage(this, pn, module); }
Called by the VM to support define package for AppCDS
/** * Called by the VM to support define package for AppCDS */
protected Package defineOrCheckPackage(String pn, Manifest man, URL url) { return super.defineOrCheckPackage(pn, man, url); } }
Attempts to convert the given string to a file URL.
API Note:This is called by the VM
/** * Attempts to convert the given string to a file URL. * * @apiNote This is called by the VM */
@Deprecated private static URL toFileURL(String s) { try { // Use an intermediate File object to construct a URI/URL without // authority component as URLClassPath can't handle URLs with a UNC // server name in the authority component. return Path.of(s).toRealPath().toFile().toURI().toURL(); } catch (InvalidPathException | IOException ignore) { // malformed path string or class path element does not exist return null; } } }