mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 10:34:38 +02:00
8256299: Implement JEP 396: Strongly Encapsulate JDK Internals by Default
Co-authored-by: Alan Bateman <alanb@openjdk.org> Reviewed-by: mchung, alanb
This commit is contained in:
parent
c47ab5f6b7
commit
ed4c4ee73b
5 changed files with 90 additions and 139 deletions
|
@ -2461,6 +2461,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
|
|||
return res;
|
||||
}
|
||||
} else if (match_option(option, "--illegal-access=", &tail)) {
|
||||
warning("Option --illegal-access is deprecated and will be removed in a future release.");
|
||||
if (!create_module_property("jdk.module.illegalAccess", tail, ExternalProperty)) {
|
||||
return JNI_ENOMEM;
|
||||
}
|
||||
|
|
|
@ -27,35 +27,27 @@ package jdk.internal.module;
|
|||
import jdk.internal.misc.CDS;
|
||||
|
||||
/**
|
||||
* Used by ModuleBootstrap for archiving the boot layer and the builder needed to
|
||||
* set the IllegalAccessLogger.
|
||||
* Used by ModuleBootstrap for archiving the boot layer.
|
||||
*/
|
||||
class ArchivedBootLayer {
|
||||
private static ArchivedBootLayer archivedBootLayer;
|
||||
|
||||
private final ModuleLayer bootLayer;
|
||||
private final IllegalAccessLogger.Builder builder;
|
||||
|
||||
private ArchivedBootLayer(ModuleLayer bootLayer,
|
||||
IllegalAccessLogger.Builder builder) {
|
||||
private ArchivedBootLayer(ModuleLayer bootLayer) {
|
||||
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 void archive(ModuleLayer layer) {
|
||||
archivedBootLayer = new ArchivedBootLayer(layer);
|
||||
}
|
||||
|
||||
static {
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
*/
|
||||
package jdk.internal.module;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleFinder;
|
||||
|
@ -33,7 +31,7 @@ import jdk.internal.misc.CDS;
|
|||
|
||||
/**
|
||||
* Used by ModuleBootstrap for archiving the configuration for the boot layer,
|
||||
* the system module finder, and the maps used to create the IllegalAccessLogger.
|
||||
* and the system module finder.
|
||||
*/
|
||||
class ArchivedModuleGraph {
|
||||
private static ArchivedModuleGraph archivedModuleGraph;
|
||||
|
@ -43,23 +41,17 @@ class ArchivedModuleGraph {
|
|||
private final ModuleFinder finder;
|
||||
private final Configuration configuration;
|
||||
private final Function<String, ClassLoader> classLoaderFunction;
|
||||
private final Map<String, Set<String>> concealedPackagesToOpen;
|
||||
private final 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) {
|
||||
Function<String, ClassLoader> classLoaderFunction) {
|
||||
this.hasSplitPackages = hasSplitPackages;
|
||||
this.hasIncubatorModules = hasIncubatorModules;
|
||||
this.finder = finder;
|
||||
this.configuration = configuration;
|
||||
this.classLoaderFunction = classLoaderFunction;
|
||||
this.concealedPackagesToOpen = concealedPackagesToOpen;
|
||||
this.exportedPackagesToOpen = exportedPackagesToOpen;
|
||||
}
|
||||
|
||||
ModuleFinder finder() {
|
||||
|
@ -74,14 +66,6 @@ class ArchivedModuleGraph {
|
|||
return classLoaderFunction;
|
||||
}
|
||||
|
||||
Map<String, Set<String>> concealedPackagesToOpen() {
|
||||
return concealedPackagesToOpen;
|
||||
}
|
||||
|
||||
Map<String, Set<String>> exportedPackagesToOpen() {
|
||||
return exportedPackagesToOpen;
|
||||
}
|
||||
|
||||
boolean hasSplitPackages() {
|
||||
return hasSplitPackages;
|
||||
}
|
||||
|
@ -110,16 +94,12 @@ class ArchivedModuleGraph {
|
|||
boolean hasIncubatorModules,
|
||||
ModuleFinder finder,
|
||||
Configuration configuration,
|
||||
Function<String, ClassLoader> classLoaderFunction,
|
||||
Map<String, Set<String>> concealedPackagesToOpen,
|
||||
Map<String, Set<String>> exportedPackagesToOpen) {
|
||||
Function<String, ClassLoader> classLoaderFunction) {
|
||||
archivedModuleGraph = new ArchivedModuleGraph(hasSplitPackages,
|
||||
hasIncubatorModules,
|
||||
finder,
|
||||
configuration,
|
||||
classLoaderFunction,
|
||||
concealedPackagesToOpen,
|
||||
exportedPackagesToOpen);
|
||||
classLoaderFunction);
|
||||
}
|
||||
|
||||
static {
|
||||
|
|
|
@ -142,13 +142,13 @@ public final class ModuleBootstrap {
|
|||
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.main") == null && // --module
|
||||
getProperty("jdk.module.addmods.0") == null && // --add-modules
|
||||
getProperty("jdk.module.limitmods") == null &&
|
||||
getProperty("jdk.module.limitmods") == null && // --limit-modules
|
||||
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;
|
||||
getProperty("jdk.module.illegalAccess") == null; // --illegal-access
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,12 +172,6 @@ public final class ModuleBootstrap {
|
|||
// 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();
|
||||
}
|
||||
|
@ -192,10 +186,10 @@ public final class ModuleBootstrap {
|
|||
ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
|
||||
ModuleFinder appModulePath = finderFor("jdk.module.path");
|
||||
boolean isPatched = patcher.hasPatches();
|
||||
|
||||
String mainModule = System.getProperty("jdk.module.main");
|
||||
Set<String> addModules = addModules();
|
||||
Set<String> limitModules = limitModules();
|
||||
String illegalAccess = getAndRemoveProperty("jdk.module.illegalAccess");
|
||||
|
||||
PrintStream traceOutput = null;
|
||||
String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
|
||||
|
@ -227,7 +221,8 @@ public final class ModuleBootstrap {
|
|||
&& !haveModulePath
|
||||
&& addModules.isEmpty()
|
||||
&& limitModules.isEmpty()
|
||||
&& !isPatched) {
|
||||
&& !isPatched
|
||||
&& illegalAccess == null) {
|
||||
systemModuleFinder = archivedModuleGraph.finder();
|
||||
hasSplitPackages = archivedModuleGraph.hasSplitPackages();
|
||||
hasIncubatorModules = archivedModuleGraph.hasIncubatorModules();
|
||||
|
@ -464,21 +459,15 @@ public final class ModuleBootstrap {
|
|||
addExtraReads(bootLayer);
|
||||
boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
|
||||
|
||||
Map<String, Set<String>> concealedPackagesToOpen;
|
||||
Map<String, Set<String>> exportedPackagesToOpen;
|
||||
if (archivedModuleGraph != null) {
|
||||
concealedPackagesToOpen = archivedModuleGraph.concealedPackagesToOpen();
|
||||
exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
|
||||
} else {
|
||||
concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
|
||||
exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
|
||||
}
|
||||
IllegalAccessLogger.Builder builder =
|
||||
addIllegalAccess(upgradeModulePath,
|
||||
concealedPackagesToOpen,
|
||||
exportedPackagesToOpen,
|
||||
if (illegalAccess != null) {
|
||||
assert systemModules != null;
|
||||
addIllegalAccess(illegalAccess,
|
||||
systemModules,
|
||||
upgradeModulePath,
|
||||
bootLayer,
|
||||
extraExportsOrOpens);
|
||||
}
|
||||
|
||||
Counters.add("jdk.module.boot.7.adjustModulesTime");
|
||||
|
||||
// save module finders for later use
|
||||
|
@ -495,12 +484,9 @@ public final class ModuleBootstrap {
|
|||
hasIncubatorModules,
|
||||
systemModuleFinder,
|
||||
cf,
|
||||
clf,
|
||||
concealedPackagesToOpen,
|
||||
exportedPackagesToOpen);
|
||||
|
||||
clf);
|
||||
if (!hasSplitPackages && !hasIncubatorModules) {
|
||||
ArchivedBootLayer.archive(bootLayer, builder);
|
||||
ArchivedBootLayer.archive(bootLayer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,38 +780,32 @@ 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.
|
||||
* Process the --illegal-access option to open packages of system modules
|
||||
* in the boot layer to code in unnamed modules.
|
||||
*/
|
||||
private static IllegalAccessLogger.Builder
|
||||
addIllegalAccess(ModuleFinder upgradeModulePath,
|
||||
Map<String, Set<String>> concealedPackagesToOpen,
|
||||
Map<String, Set<String>> exportedPackagesToOpen,
|
||||
private static void addIllegalAccess(String illegalAccess,
|
||||
SystemModules systemModules,
|
||||
ModuleFinder upgradeModulePath,
|
||||
ModuleLayer bootLayer,
|
||||
boolean extraExportsOrOpens) {
|
||||
String value = getAndRemoveProperty("jdk.module.illegalAccess");
|
||||
IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
|
||||
if (value != null) {
|
||||
switch (value) {
|
||||
case "deny":
|
||||
return null;
|
||||
case "permit":
|
||||
break;
|
||||
case "warn":
|
||||
mode = IllegalAccessLogger.Mode.WARN;
|
||||
break;
|
||||
case "debug":
|
||||
mode = IllegalAccessLogger.Mode.DEBUG;
|
||||
break;
|
||||
default:
|
||||
fail("Value specified to --illegal-access not recognized:"
|
||||
+ " '" + value + "'");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
IllegalAccessLogger.Builder builder
|
||||
= new IllegalAccessLogger.Builder(mode, System.err);
|
||||
|
||||
if (illegalAccess.equals("deny"))
|
||||
return; // nothing to do
|
||||
|
||||
IllegalAccessLogger.Mode mode = switch (illegalAccess) {
|
||||
case "permit" -> IllegalAccessLogger.Mode.ONESHOT;
|
||||
case "warn" -> IllegalAccessLogger.Mode.WARN;
|
||||
case "debug" -> IllegalAccessLogger.Mode.DEBUG;
|
||||
default -> {
|
||||
fail("Value specified to --illegal-access not recognized:"
|
||||
+ " '" + illegalAccess + "'");
|
||||
yield null;
|
||||
}
|
||||
};
|
||||
|
||||
var builder = new IllegalAccessLogger.Builder(mode, System.err);
|
||||
Map<String, Set<String>> concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
|
||||
Map<String, Set<String>> exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
|
||||
if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
|
||||
// need to generate (exploded build)
|
||||
IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
|
||||
|
@ -887,7 +867,6 @@ public final class ModuleBootstrap {
|
|||
}
|
||||
|
||||
builder.complete();
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
@ -239,15 +239,15 @@ public class IllegalAccessTest {
|
|||
}
|
||||
|
||||
@Test(dataProvider = "denyCases")
|
||||
public void testDeny(String action, Result expectedResult) throws Exception {
|
||||
run(action, expectedResult, "--illegal-access=deny");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "permitCases")
|
||||
public void testDefault(String action, Result expectedResult) throws Exception {
|
||||
run(action, expectedResult);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "denyCases")
|
||||
public void testDeny(String action, Result expectedResult) throws Exception {
|
||||
run(action, expectedResult, "--illegal-access=deny");
|
||||
}
|
||||
|
||||
@Test(dataProvider = "permitCases")
|
||||
public void testPermit(String action, Result expectedResult) throws Exception {
|
||||
run(action, expectedResult, "--illegal-access=permit");
|
||||
|
@ -267,41 +267,42 @@ public class IllegalAccessTest {
|
|||
run(action, expectedResult, "--illegal-access=debug");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify --add-exports to export a package
|
||||
*/
|
||||
public void testWithAddExportsOption() throws Exception {
|
||||
// warning
|
||||
run("reflectPublicMemberNonExportedPackage", successWithWarning());
|
||||
// not accessible
|
||||
run("reflectPublicMemberNonExportedPackage", fail("IllegalAccessException"));
|
||||
|
||||
// no warning due to --add-exports
|
||||
// should succeed with --add-exports
|
||||
run("reflectPublicMemberNonExportedPackage", successNoWarning(),
|
||||
"--add-exports", "java.base/sun.security.x509=ALL-UNNAMED");
|
||||
|
||||
// attempt two illegal accesses, one allowed by --add-exports
|
||||
run("reflectPublicMemberNonExportedPackage"
|
||||
+ ",setAccessibleNonPublicMemberExportedPackage",
|
||||
successWithWarning(),
|
||||
"--add-exports", "java.base/sun.security.x509=ALL-UNNAMED");
|
||||
// not accessible
|
||||
run("setAccessibleNonPublicMemberNonExportedPackage", fail("InaccessibleObjectException"));
|
||||
|
||||
// should fail as --add-exports does not open package
|
||||
run("setAccessibleNonPublicMemberNonExportedPackage", fail("InaccessibleObjectException"),
|
||||
"--add-exports", "java.base/sun.nio.ch=ALL-UNNAMED");
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify --add-open to open a package
|
||||
*/
|
||||
public void testWithAddOpensOption() throws Exception {
|
||||
// warning
|
||||
run("setAccessibleNonPublicMemberExportedPackage", successWithWarning());
|
||||
// not accessible
|
||||
run("reflectPublicMemberNonExportedPackage", fail("IllegalAccessException"));
|
||||
|
||||
// no warning due to --add-opens
|
||||
// should succeed with --add-opens
|
||||
run("reflectPublicMemberNonExportedPackage", successNoWarning(),
|
||||
"--add-opens", "java.base/sun.security.x509=ALL-UNNAMED");
|
||||
|
||||
// not accessible
|
||||
run("setAccessibleNonPublicMemberExportedPackage", fail("InaccessibleObjectException"));
|
||||
|
||||
// should succeed with --add-opens
|
||||
run("setAccessibleNonPublicMemberExportedPackage", successNoWarning(),
|
||||
"--add-opens", "java.base/java.lang=ALL-UNNAMED");
|
||||
|
||||
// attempt two illegal accesses, one allowed by --add-opens
|
||||
run("reflectPublicMemberNonExportedPackage"
|
||||
+ ",setAccessibleNonPublicMemberExportedPackage",
|
||||
successWithWarning(),
|
||||
"--add-opens", "java.base/java.lang=ALL-UNNAMED");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -373,19 +374,20 @@ public class IllegalAccessTest {
|
|||
Attributes attrs = man.getMainAttributes();
|
||||
attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
attrs.put(Attributes.Name.MAIN_CLASS, "TryAccess");
|
||||
attrs.put(new Attributes.Name("Add-Exports"), "java.base/sun.security.x509");
|
||||
attrs.put(new Attributes.Name("Add-Exports"),
|
||||
"java.base/sun.security.x509 java.base/sun.nio.ch");
|
||||
Path jarfile = Paths.get("x.jar");
|
||||
Path classes = Paths.get(TEST_CLASSES);
|
||||
JarUtils.createJarFile(jarfile, man, classes, Paths.get("TryAccess.class"));
|
||||
|
||||
run(jarfile, "reflectPublicMemberNonExportedPackage", successNoWarning());
|
||||
|
||||
run(jarfile, "setAccessibleNonPublicMemberExportedPackage", successWithWarning());
|
||||
run(jarfile, "reflectPublicMemberNonExportedPackage", successNoWarning(),
|
||||
"--illegal-access=permit");
|
||||
|
||||
// attempt two illegal accesses, one allowed by Add-Exports
|
||||
run(jarfile, "reflectPublicMemberNonExportedPackage,"
|
||||
+ "setAccessibleNonPublicMemberExportedPackage",
|
||||
successWithWarning());
|
||||
// should fail as Add-Exports does not open package
|
||||
run(jarfile, "setAccessibleNonPublicMemberNonExportedPackage",
|
||||
fail("InaccessibleObjectException"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -403,29 +405,26 @@ public class IllegalAccessTest {
|
|||
|
||||
run(jarfile, "setAccessibleNonPublicMemberExportedPackage", successNoWarning());
|
||||
|
||||
run(jarfile, "reflectPublicMemberNonExportedPackage", successWithWarning());
|
||||
|
||||
// attempt two illegal accesses, one allowed by Add-Opens
|
||||
run(jarfile, "reflectPublicMemberNonExportedPackage,"
|
||||
+ "setAccessibleNonPublicMemberExportedPackage",
|
||||
successWithWarning());
|
||||
run(jarfile, "setAccessibleNonPublicMemberExportedPackage", successNoWarning(),
|
||||
"--illegal-access=permit");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that default behavior is to print a warning on the first illegal
|
||||
* access only.
|
||||
* Test that --illegal-access=permit behavior is to print a warning on the
|
||||
* first illegal access only.
|
||||
*/
|
||||
public void testWarnOnFirstIllegalAccess() throws Exception {
|
||||
String action1 = "reflectPublicMemberNonExportedPackage";
|
||||
String action2 = "setAccessibleNonPublicMemberExportedPackage";
|
||||
int warningCount = count(run(action1).asLines(), "WARNING");
|
||||
int warningCount = count(run(action1, "--illegal-access=permit").asLines(), "WARNING");
|
||||
assertTrue(warningCount > 0); // multi line warning
|
||||
|
||||
// same illegal access
|
||||
List<String> output1 = run(action1 + "," + action1).asLines();
|
||||
List<String> output1 = run(action1 + "," + action1, "--illegal-access=permit").asLines();
|
||||
assertTrue(count(output1, "WARNING") == warningCount);
|
||||
|
||||
// different illegal access
|
||||
List<String> output2 = run(action1 + "," + action2).asLines();
|
||||
List<String> output2 = run(action1 + "," + action2, "--illegal-access=permit").asLines();
|
||||
assertTrue(count(output2, "WARNING") == warningCount);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue