--- a/jdk/src/java.base/share/classes/java/lang/SecurityManager.java Mon Apr 24 13:43:34 2017 +0800
+++ b/jdk/src/java.base/share/classes/java/lang/SecurityManager.java Thu May 04 07:26:55 2017 +0000
@@ -25,10 +25,10 @@
package java.lang;
-import java.lang.RuntimePermission;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Opens;
+import java.lang.module.ModuleReference;
import java.lang.reflect.Member;
import java.io.FileDescriptor;
import java.io.File;
@@ -42,12 +42,15 @@
import java.security.Security;
import java.security.SecurityPermission;
import java.util.HashSet;
+import java.util.Map;
import java.util.Objects;
import java.util.PropertyPermission;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
+import jdk.internal.module.ModuleBootstrap;
+import jdk.internal.module.ModuleLoaderMap;
import jdk.internal.reflect.CallerSensitive;
import sun.security.util.SecurityConstants;
@@ -1431,29 +1434,29 @@
return packages;
}
- // The non-exported packages of the modules in the boot layer that are
- // loaded by the platform class loader or its ancestors. A non-exported
- // package is a package that either is not exported at all by its containing
- // module or is exported in a qualified fashion by its containing module.
- private static final Set<String> nonExportedPkgs;
-
+ // The non-exported packages in modules defined to the boot or platform
+ // class loaders. A non-exported package is a package that is not exported
+ // or is only exported to specific modules.
+ private static final Map<String, Boolean> nonExportedPkgs = new ConcurrentHashMap<>();
static {
- // Get the modules in the boot layer
- Stream<Module> bootLayerModules = ModuleLayer.boot().modules().stream();
+ addNonExportedPackages(ModuleLayer.boot());
+ }
- // Filter out the modules loaded by the boot or platform loader
- PrivilegedAction<Set<Module>> pa = () ->
- bootLayerModules.filter(SecurityManager::isBootOrPlatformModule)
- .collect(Collectors.toSet());
- Set<Module> modules = AccessController.doPrivileged(pa);
+ /**
+ * Record the non-exported packages of the modules in the given layer
+ */
+ static void addNonExportedPackages(ModuleLayer layer) {
+ Set<String> bootModules = ModuleLoaderMap.bootModules();
+ Set<String> platformModules = ModuleLoaderMap.platformModules();
+ layer.modules().stream()
+ .map(Module::getDescriptor)
+ .filter(md -> bootModules.contains(md.name())
+ || platformModules.contains(md.name()))
+ .map(SecurityManager::nonExportedPkgs)
+ .flatMap(Set::stream)
+ .forEach(pn -> nonExportedPkgs.put(pn, Boolean.TRUE));
+ }
- // Filter out the non-exported packages
- nonExportedPkgs = modules.stream()
- .map(Module::getDescriptor)
- .map(SecurityManager::nonExportedPkgs)
- .flatMap(Set::stream)
- .collect(Collectors.toSet());
- }
/**
* Called by java.security.Security
@@ -1468,14 +1471,6 @@
}
/**
- * Returns true if the module's loader is the boot or platform loader.
- */
- private static boolean isBootOrPlatformModule(Module m) {
- return m.getClassLoader() == null ||
- m.getClassLoader() == ClassLoader.getPlatformClassLoader();
- }
-
- /**
* Returns the non-exported packages of the specified module.
*/
private static Set<String> nonExportedPkgs(ModuleDescriptor md) {
@@ -1535,7 +1530,7 @@
Objects.requireNonNull(pkg, "package name can't be null");
// check if pkg is not exported to all modules
- if (nonExportedPkgs.contains(pkg)) {
+ if (nonExportedPkgs.containsKey(pkg)) {
checkPermission(
new RuntimePermission("accessClassInPackage." + pkg));
return;
@@ -1634,7 +1629,7 @@
Objects.requireNonNull(pkg, "package name can't be null");
// check if pkg is not exported to all modules
- if (nonExportedPkgs.contains(pkg)) {
+ if (nonExportedPkgs.containsKey(pkg)) {
checkPermission(
new RuntimePermission("defineClassInPackage." + pkg));
return;