|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
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. |
|
*/ |
|
|
|
public class ClassLoaders { |
|
|
|
private ClassLoaders() { } |
|
|
|
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); |
|
|
|
|
|
private static final BootClassLoader BOOT_LOADER; |
|
private static final PlatformClassLoader PLATFORM_LOADER; |
|
private static final AppClassLoader APP_LOADER; |
|
|
|
|
|
static { |
|
|
|
String append = VM.getSavedProperty("jdk.boot.class.path.append"); |
|
BOOT_LOADER = |
|
new BootClassLoader((append != null && append.length() > 0) |
|
? 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 cp = System.getProperty("java.class.path"); |
|
if (cp == null || cp.length() == 0) { |
|
String initialModuleName = System.getProperty("jdk.module.main"); |
|
cp = (initialModuleName == null) ? "" : null; |
|
} |
|
URLClassPath ucp = new URLClassPath(cp, false); |
|
APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
static BuiltinClassLoader bootLoader() { |
|
return BOOT_LOADER; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public static ClassLoader platformClassLoader() { |
|
return PLATFORM_LOADER; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public static ClassLoader appClassLoader() { |
|
return APP_LOADER; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static class BootClassLoader extends BuiltinClassLoader { |
|
BootClassLoader(URLClassPath bcp) { |
|
super(null, null, bcp); |
|
} |
|
|
|
@Override |
|
protected Class<?> loadClassOrNull(String cn) { |
|
return JLA.findBootstrapClassOrNull(this, cn); |
|
} |
|
}; |
|
|
|
|
|
|
|
|
|
*/ |
|
private static class PlatformClassLoader extends BuiltinClassLoader { |
|
static { |
|
if (!ClassLoader.registerAsParallelCapable()) |
|
throw new InternalError(); |
|
} |
|
|
|
PlatformClassLoader(BootClassLoader parent) { |
|
super("platform", parent, null); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private Package definePackage(String pn, Module module) { |
|
return JLA.definePackage(this, pn, module); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
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 |
|
|
|
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; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
void appendToClassPathForInstrumentation(String path) { |
|
ucp.addFile(path); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private Package definePackage(String pn, Module module) { |
|
return JLA.definePackage(this, pn, module); |
|
} |
|
|
|
|
|
|
|
*/ |
|
protected Package defineOrCheckPackage(String pn, Manifest man, URL url) { |
|
return super.defineOrCheckPackage(pn, man, url); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
@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 |
|
|
|
return Path.of(s).toRealPath().toFile().toURI().toURL(); |
|
} catch (InvalidPathException | IOException ignore) { |
|
|
|
return null; |
|
} |
|
} |
|
} |