8244778: Archive full module graph in CDS

Reviewed-by: erikj, coleenp, lfoltan, redestad, alanb, mchung
This commit is contained in:
Ioi Lam 2020-09-13 14:45:12 +00:00
parent 998ce78e53
commit 03a4df0acd
59 changed files with 2052 additions and 164 deletions

View file

@ -2714,6 +2714,17 @@ public abstract class ClassLoader {
offset = unsafe.objectFieldOffset(k, name);
return unsafe.compareAndSetReference(this, offset, null, obj);
}
/**
* Called by the VM, during -Xshare:dump
*/
private void resetArchivedStates() {
parallelLockMap.clear();
packages.clear();
package2certs.clear();
classes.clear();
classLoaderValueMap = null;
}
}
/*

View file

@ -55,6 +55,7 @@ import java.util.stream.Stream;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.ClassLoaders;
import jdk.internal.misc.VM;
import jdk.internal.module.IllegalAccessLogger;
import jdk.internal.module.ModuleLoaderMap;
import jdk.internal.module.ServicesCatalog;
@ -246,12 +247,55 @@ public final class Module implements AnnotatedElement {
// --
// special Module to mean "all unnamed modules"
private static final Module ALL_UNNAMED_MODULE = new Module(null);
private static final Set<Module> ALL_UNNAMED_MODULE_SET = Set.of(ALL_UNNAMED_MODULE);
private static final Module ALL_UNNAMED_MODULE;
private static final Set<Module> ALL_UNNAMED_MODULE_SET;
// special Module to mean "everyone"
private static final Module EVERYONE_MODULE = new Module(null);
private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
private static final Module EVERYONE_MODULE;
private static final Set<Module> EVERYONE_SET;
private static class ArchivedData {
private static ArchivedData archivedData;
private final Module allUnnamedModule;
private final Set<Module> allUnnamedModules;
private final Module everyoneModule;
private final Set<Module> everyoneSet;
private ArchivedData() {
this.allUnnamedModule = ALL_UNNAMED_MODULE;
this.allUnnamedModules = ALL_UNNAMED_MODULE_SET;
this.everyoneModule = EVERYONE_MODULE;
this.everyoneSet = EVERYONE_SET;
}
static void archive() {
archivedData = new ArchivedData();
}
static ArchivedData get() {
return archivedData;
}
static {
VM.initializeFromArchive(ArchivedData.class);
}
}
static {
ArchivedData archivedData = ArchivedData.get();
if (archivedData != null) {
ALL_UNNAMED_MODULE = archivedData.allUnnamedModule;
ALL_UNNAMED_MODULE_SET = archivedData.allUnnamedModules;
EVERYONE_MODULE = archivedData.everyoneModule;
EVERYONE_SET = archivedData.everyoneSet;
} else {
ALL_UNNAMED_MODULE = new Module(null);
ALL_UNNAMED_MODULE_SET = Set.of(ALL_UNNAMED_MODULE);
EVERYONE_MODULE = new Module(null);
EVERYONE_SET = Set.of(EVERYONE_MODULE);
ArchivedData.archive();
}
}
/**
* The holder of data structures to support readability, exports, and

View file

@ -2248,6 +2248,9 @@ public final class System {
public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
return layer.getServicesCatalog();
}
public void bindToLoader(ModuleLayer layer, ClassLoader loader) {
layer.bindToLoader(loader);
}
public Stream<ModuleLayer> layers(ModuleLayer layer) {
return layer.layers();
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2020, 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
@ -269,4 +269,11 @@ public class SecureClassLoader extends ClassLoader {
return cs.matchCerts(csk.cs, true);
}
}
/**
* Called by the VM, during -Xshare:dump
*/
private void resetArchivedStates() {
pdcache.clear();
}
}

View file

@ -256,6 +256,12 @@ public interface JavaLangAccess {
*/
ServicesCatalog getServicesCatalog(ModuleLayer layer);
/**
* Record that this layer has at least one module defined to the given
* class loader.
*/
void bindToLoader(ModuleLayer layer, ClassLoader loader);
/**
* Returns an ordered stream of layers. The first element is the
* given layer, the remaining elements are its parents, in DFS order.

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2020, 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.util.Map;
import jdk.internal.misc.VM;
import jdk.internal.module.ServicesCatalog;
/**
* Used to archive the built-in class loaders, their services catalogs, and the
* package-to-module map used by the built-in class loaders.
*/
class ArchivedClassLoaders {
private static ArchivedClassLoaders archivedClassLoaders;
private final ClassLoader bootLoader;
private final ClassLoader platformLoader;
private final ClassLoader appLoader;
private final ServicesCatalog[] servicesCatalogs;
private final Map<String, ?> packageToModule;
private ArchivedClassLoaders() {
bootLoader = ClassLoaders.bootLoader();
platformLoader = ClassLoaders.platformClassLoader();
appLoader = ClassLoaders.appClassLoader();
servicesCatalogs = new ServicesCatalog[3];
servicesCatalogs[0] = BootLoader.getServicesCatalog();
servicesCatalogs[1] = ServicesCatalog.getServicesCatalog(platformLoader);
servicesCatalogs[2] = ServicesCatalog.getServicesCatalog(appLoader);
packageToModule = BuiltinClassLoader.packageToModule();
}
ClassLoader bootLoader() {
return bootLoader;
}
ClassLoader platformLoader() {
return platformLoader;
}
ClassLoader appLoader() {
return appLoader;
}
ServicesCatalog servicesCatalog(ClassLoader loader) {
if (loader == null) {
return servicesCatalogs[0];
} else if (loader == platformLoader) {
return servicesCatalogs[1];
} else if (loader == appLoader) {
return servicesCatalogs[2];
} else {
throw new InternalError();
}
}
Map<String, ?> packageToModule() {
return packageToModule;
}
static void archive() {
archivedClassLoaders = new ArchivedClassLoaders();
}
static ArchivedClassLoaders get() {
return archivedClassLoaders;
}
static {
VM.initializeFromArchive(ArchivedClassLoaders.class);
}
}

View file

@ -65,7 +65,15 @@ public class BootLoader {
}
// ServiceCatalog for the boot class loader
private static final ServicesCatalog SERVICES_CATALOG = ServicesCatalog.create();
private static final ServicesCatalog SERVICES_CATALOG;
static {
ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
if (archivedClassLoaders != null) {
SERVICES_CATALOG = archivedClassLoaders.servicesCatalog(null);
} else {
SERVICES_CATALOG = ServicesCatalog.create();
}
}
// ClassLoaderValue map for the boot class loader
private static final ConcurrentHashMap<?, ?> CLASS_LOADER_VALUE_MAP

View file

@ -104,8 +104,7 @@ public class BuiltinClassLoader
private final BuiltinClassLoader parent;
// the URL class path, or null if there is no class path
private final URLClassPath ucp;
private @Stable URLClassPath ucp;
/**
* A module defined/loaded by a built-in class loader.
@ -156,10 +155,26 @@ public class BuiltinClassLoader
}
}
// maps package name to loaded module for modules in the boot layer
private static final Map<String, LoadedModule> packageToModule
= new ConcurrentHashMap<>(1024);
private static final Map<String, LoadedModule> packageToModule;
static {
ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
if (archivedClassLoaders != null) {
@SuppressWarnings("unchecked")
Map<String, LoadedModule> map
= (Map<String, LoadedModule>) archivedClassLoaders.packageToModule();
packageToModule = map;
} else {
packageToModule = new ConcurrentHashMap<>(1024);
}
}
/**
* Invoked by ArchivedClassLoaders to archive the package-to-module map.
*/
static Map<String, ?> packageToModule() {
return packageToModule;
}
// maps a module name to a module reference
private final Map<String, ModuleReference> nameToModule;
@ -185,6 +200,21 @@ public class BuiltinClassLoader
this.moduleToReader = new ConcurrentHashMap<>();
}
/**
* Appends to the given file path to the class path.
*/
void appendClassPath(String path) {
// assert ucp != null;
ucp.addFile(path);
}
/**
* Sets the class path, called to reset the class path during -Xshare:dump
*/
void setClassPath(URLClassPath ucp) {
this.ucp = ucp;
}
/**
* Returns {@code true} if there is a class path associated with this
* class loader.
@ -1042,4 +1072,9 @@ public class BuiltinClassLoader
private static URL checkURL(URL url) {
return URLClassPath.checkURL(url);
}
// Called from VM only, during -Xshare:dump
private void resetArchivedStates() {
ucp = null;
}
}

View file

@ -36,6 +36,7 @@ import java.util.jar.Manifest;
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.VM;
import jdk.internal.module.ServicesCatalog;
/**
* Creates and provides access to the built-in platform and application class
@ -56,14 +57,22 @@ public class ClassLoaders {
// 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);
ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
if (archivedClassLoaders != null) {
// assert VM.getSavedProperty("jdk.boot.class.path.append") == null
BOOT_LOADER = (BootClassLoader) archivedClassLoaders.bootLoader();
PLATFORM_LOADER = (PlatformClassLoader) archivedClassLoaders.platformLoader();
ServicesCatalog catalog = archivedClassLoaders.servicesCatalog(PLATFORM_LOADER);
ServicesCatalog.putServicesCatalog(PLATFORM_LOADER, catalog);
} else {
// -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute
String append = VM.getSavedProperty("jdk.boot.class.path.append");
URLClassPath ucp = (append != null && !append.isEmpty())
? new URLClassPath(append, true)
: null;
BOOT_LOADER = new BootClassLoader(ucp);
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
@ -75,7 +84,15 @@ public class ClassLoaders {
cp = (initialModuleName == null) ? "" : null;
}
URLClassPath ucp = new URLClassPath(cp, false);
APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp);
if (archivedClassLoaders != null) {
APP_LOADER = (AppClassLoader) archivedClassLoaders.appLoader();
ServicesCatalog catalog = archivedClassLoaders.servicesCatalog(APP_LOADER);
ServicesCatalog.putServicesCatalog(APP_LOADER, catalog);
APP_LOADER.setClassPath(ucp);
} else {
APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp);
ArchivedClassLoaders.archive();
}
}
/**
@ -144,11 +161,8 @@ public class ClassLoaders {
throw new InternalError();
}
final URLClassPath ucp;
AppClassLoader(PlatformClassLoader parent, URLClassPath ucp) {
AppClassLoader(BuiltinClassLoader parent, URLClassPath ucp) {
super("app", parent, ucp);
this.ucp = ucp;
}
@Override
@ -181,7 +195,7 @@ public class ClassLoaders {
* @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch
*/
void appendToClassPathForInstrumentation(String path) {
ucp.addFile(path);
appendClassPath(path);
}
/**
@ -190,6 +204,13 @@ public class ClassLoaders {
protected Package defineOrCheckPackage(String pn, Manifest man, URL url) {
return super.defineOrCheckPackage(pn, man, url);
}
/**
* Called by the VM, during -Xshare:dump
*/
private void resetArchivedStates() {
setClassPath(null);
}
}
/**

View file

@ -468,6 +468,8 @@ public class VM {
*/
public static native void initializeFromArchive(Class<?> c);
public static native void defineArchivedModules(ClassLoader platformLoader, ClassLoader systemLoader);
public static native long getRandomSeedForCDSDump();
/**

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2020, 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.module;
import jdk.internal.misc.VM;
/**
* Used by ModuleBootstrap for archiving the boot layer and the builder needed to
* set the IllegalAccessLogger.
*/
class ArchivedBootLayer {
private static ArchivedBootLayer archivedBootLayer;
private final ModuleLayer bootLayer;
private final IllegalAccessLogger.Builder builder;
private ArchivedBootLayer(ModuleLayer bootLayer,
IllegalAccessLogger.Builder builder) {
this.bootLayer = bootLayer;
this.builder = builder;
}
ModuleLayer bootLayer() {
return bootLayer;
}
IllegalAccessLogger.Builder illegalAccessLoggerBuilder() {
return builder;
}
static ArchivedBootLayer get() {
return archivedBootLayer;
}
static void archive(ModuleLayer layer, IllegalAccessLogger.Builder builder) {
archivedBootLayer = new ArchivedBootLayer(layer, builder);
}
static {
VM.initializeFromArchive(ArchivedBootLayer.class);
}
}

View file

@ -22,21 +22,20 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.module;
import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import jdk.internal.misc.VM;
/**
* Used by ModuleBootstrap to obtain the archived system modules and finder.
* Used by ModuleBootstrap for archiving the configuration for the boot layer,
* the system module finder, and the maps used to create the IllegalAccessLogger.
*/
final class ArchivedModuleGraph {
class ArchivedModuleGraph {
private static ArchivedModuleGraph archivedModuleGraph;
private final boolean hasSplitPackages;
@ -47,13 +46,13 @@ final class ArchivedModuleGraph {
private final Map<String, Set<String>> concealedPackagesToOpen;
private final Map<String, Set<String>> exportedPackagesToOpen;
public ArchivedModuleGraph(boolean hasSplitPackages,
boolean hasIncubatorModules,
ModuleFinder finder,
Configuration configuration,
Function<String, ClassLoader> classLoaderFunction,
Map<String, Set<String>> concealedPackagesToOpen,
Map<String, Set<String>> exportedPackagesToOpen) {
private ArchivedModuleGraph(boolean hasSplitPackages,
boolean hasIncubatorModules,
ModuleFinder finder,
Configuration configuration,
Function<String, ClassLoader> classLoaderFunction,
Map<String, Set<String>> concealedPackagesToOpen,
Map<String, Set<String>> exportedPackagesToOpen) {
this.hasSplitPackages = hasSplitPackages;
this.hasIncubatorModules = hasIncubatorModules;
this.finder = finder;
@ -107,8 +106,20 @@ final class ArchivedModuleGraph {
/**
* Archive the module graph for the given initial module.
*/
static void archive(ArchivedModuleGraph graph) {
archivedModuleGraph = graph;
static void archive(boolean hasSplitPackages,
boolean hasIncubatorModules,
ModuleFinder finder,
Configuration configuration,
Function<String, ClassLoader> classLoaderFunction,
Map<String, Set<String>> concealedPackagesToOpen,
Map<String, Set<String>> exportedPackagesToOpen) {
archivedModuleGraph = new ArchivedModuleGraph(hasSplitPackages,
hasIncubatorModules,
finder,
configuration,
classLoaderFunction,
concealedPackagesToOpen,
exportedPackagesToOpen);
}
static {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2020, 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
@ -57,7 +57,7 @@ public final class IllegalAccessLogger {
/**
* Logger modes
*/
public static enum Mode {
public enum Mode {
/**
* Prints a warning when an illegal access succeeds and then
* discards the logger so that there is no further output.
@ -118,7 +118,7 @@ public final class IllegalAccessLogger {
}
/**
* Builds the IllegalAccessLogger and sets it as the system-wise logger.
* Builds the IllegalAccessLogger and sets it as the system-wide logger.
*/
public void complete() {
Map<Module, Set<String>> map1 = unmodifiableMap(moduleToConcealedPackages);

View file

@ -42,18 +42,19 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.JavaLangModuleAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.loader.ClassLoaders;
import jdk.internal.misc.VM;
import jdk.internal.perf.PerfCounter;
/**
@ -86,8 +87,8 @@ public final class ModuleBootstrap {
private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
// access to java.lang/module
private static final JavaLangModuleAccess JLMA
= SharedSecrets.getJavaLangModuleAccess();
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
// The ModulePatcher for the initial configuration
private static final ModulePatcher patcher = initModulePatcher();
@ -134,14 +135,58 @@ public final class ModuleBootstrap {
}
/**
* Initialize the module system, returning the boot layer.
* Returns true if the archived boot layer can be used. The system properties
* are checked in the order that they are used by boot2.
*/
private static boolean canUseArchivedBootLayer() {
return getProperty("jdk.module.upgrade.path") == null &&
getProperty("jdk.module.path") == null &&
getProperty("jdk.module.patch.0") == null && // --patch-module
getProperty("jdk.module.main") == null &&
getProperty("jdk.module.addmods.0") == null && // --add-modules
getProperty("jdk.module.limitmods") == null &&
getProperty("jdk.module.addreads.0") == null && // --add-reads
getProperty("jdk.module.addexports.0") == null && // --add-exports
getProperty("jdk.module.addopens.0") == null && // --add-opens
getProperty("jdk.module.illegalAccess") == null;
}
/**
* Initialize the module system, returning the boot layer. The boot layer
* is obtained from the CDS archive if possible, otherwise it is generated
* from the module graph.
*
* @see java.lang.System#initPhase2(boolean, boolean)
*/
public static ModuleLayer boot() throws Exception {
public static ModuleLayer boot() {
Counters.start();
ModuleLayer bootLayer;
ArchivedBootLayer archivedBootLayer = ArchivedBootLayer.get();
if (archivedBootLayer != null) {
assert canUseArchivedBootLayer();
bootLayer = archivedBootLayer.bootLayer();
BootLoader.getUnnamedModule(); // trigger <clinit> of BootLoader.
VM.defineArchivedModules(ClassLoaders.platformClassLoader(), ClassLoaders.appClassLoader());
// assume boot layer has at least one module providing a service
// that is mapped to the application class loader.
JLA.bindToLoader(bootLayer, ClassLoaders.appClassLoader());
// IllegalAccessLogger needs to be set
var illegalAccessLoggerBuilder = archivedBootLayer.illegalAccessLoggerBuilder();
if (illegalAccessLoggerBuilder != null) {
illegalAccessLoggerBuilder.complete();
}
} else {
bootLayer = boot2();
}
Counters.publish("jdk.module.boot.totalTime");
return bootLayer;
}
private static ModuleLayer boot2() {
// Step 0: Command line options
ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
@ -428,11 +473,12 @@ public final class ModuleBootstrap {
concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
}
addIllegalAccess(upgradeModulePath,
concealedPackagesToOpen,
exportedPackagesToOpen,
bootLayer,
extraExportsOrOpens);
IllegalAccessLogger.Builder builder =
addIllegalAccess(upgradeModulePath,
concealedPackagesToOpen,
exportedPackagesToOpen,
bootLayer,
extraExportsOrOpens);
Counters.add("jdk.module.boot.7.adjustModulesTime");
// save module finders for later use
@ -442,21 +488,21 @@ public final class ModuleBootstrap {
limitedFinder = new SafeModuleFinder(finder);
}
// Module graph can be archived at CDS dump time. Only allow the
// unnamed module case for now.
// Archive module graph and boot layer can be archived at CDS dump time.
// Only allow the unnamed module case for now.
if (canArchive && (mainModule == null)) {
ArchivedModuleGraph.archive(
new ArchivedModuleGraph(hasSplitPackages,
hasIncubatorModules,
systemModuleFinder,
cf,
clf,
concealedPackagesToOpen,
exportedPackagesToOpen));
}
ArchivedModuleGraph.archive(hasSplitPackages,
hasIncubatorModules,
systemModuleFinder,
cf,
clf,
concealedPackagesToOpen,
exportedPackagesToOpen);
// total time to initialize
Counters.publish("jdk.module.boot.totalTime");
if (!hasSplitPackages && !hasIncubatorModules) {
ArchivedBootLayer.archive(bootLayer, builder);
}
}
return bootLayer;
}
@ -751,17 +797,18 @@ public final class ModuleBootstrap {
* Process the --illegal-access option (and its default) to open packages
* of system modules in the boot layer to code in unnamed modules.
*/
private static void addIllegalAccess(ModuleFinder upgradeModulePath,
Map<String, Set<String>> concealedPackagesToOpen,
Map<String, Set<String>> exportedPackagesToOpen,
ModuleLayer bootLayer,
boolean extraExportsOrOpens) {
private static IllegalAccessLogger.Builder
addIllegalAccess(ModuleFinder upgradeModulePath,
Map<String, Set<String>> concealedPackagesToOpen,
Map<String, Set<String>> exportedPackagesToOpen,
ModuleLayer bootLayer,
boolean extraExportsOrOpens) {
String value = getAndRemoveProperty("jdk.module.illegalAccess");
IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
if (value != null) {
switch (value) {
case "deny":
return;
return null;
case "permit":
break;
case "warn":
@ -773,7 +820,7 @@ public final class ModuleBootstrap {
default:
fail("Value specified to --illegal-access not recognized:"
+ " '" + value + "'");
return;
return null;
}
}
IllegalAccessLogger.Builder builder
@ -836,11 +883,11 @@ public final class ModuleBootstrap {
builder.logAccessToExportedPackages(m, exportedPackages);
// open the packages to unnamed modules
JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
jla.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
JLA.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
}
builder.complete();
return builder;
}
/**
@ -905,11 +952,19 @@ public final class ModuleBootstrap {
return decode(prefix, ",", true);
}
/**
* Gets the named system property
*/
private static String getProperty(String key) {
return System.getProperty(key);
}
/**
* Gets and remove the named system property
*/
private static String getAndRemoveProperty(String key) {
return (String)System.getProperties().remove(key);
return (String) System.getProperties().remove(key);
}
/**

View file

@ -171,6 +171,16 @@ public final class ServicesCatalog {
return catalog;
}
/**
* Associates the given ServicesCatalog with the given class loader.
*/
public static void putServicesCatalog(ClassLoader loader, ServicesCatalog catalog) {
ServicesCatalog previous = CLV.putIfAbsent(loader, catalog);
if (previous != null) {
throw new InternalError();
}
}
// the ServicesCatalog registered to a class loader
private static final ClassLoaderValue<ServicesCatalog> CLV = new ClassLoaderValue<>();
}

View file

@ -62,6 +62,13 @@ Java_jdk_internal_misc_VM_initializeFromArchive(JNIEnv *env, jclass ignore,
JVM_InitializeFromArchive(env, c);
}
JNIEXPORT void JNICALL
Java_jdk_internal_misc_VM_defineArchivedModules(JNIEnv *env, jclass ignore,
jobject platform_loader,
jobject system_loader) {
JVM_DefineArchivedModules(env, platform_loader, system_loader);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_misc_VM_getRandomSeedForCDSDump(JNIEnv *env, jclass ignore) {
return JVM_GetRandomSeedForCDSDump();