--- old/src/java.base/share/classes/java/lang/reflect/Layer.java 2017-03-21 13:43:59.604186821 +0000 +++ new/src/java.base/share/classes/java/lang/reflect/Layer.java 2017-03-21 13:43:59.402172959 +0000 @@ -66,9 +66,7 @@ * ResolvedModule} in the configuration. For each resolved module that is * {@link ResolvedModule#reads() read}, the {@code Module} {@link * Module#canRead reads} the corresponding run-time {@code Module}, which may - * be in the same layer or a {@link #parents() parent} layer. The {@code Module} - * {@link Module#isExported(String) exports} and {@link Module#isOpen(String) - * opens} the packages described by its {@link ModuleDescriptor}.

+ * be in the same layer or a {@link #parents() parent} layer.

* *

The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and * {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods @@ -91,6 +89,28 @@ * built-in into the Java virtual machine. The boot layer will often be * the {@link #parents() parent} when creating additional layers.

* + *

Each {@code Module} in a layer is created so that it {@link + * Module#isExported(String) exports} and {@link Module#isOpen(String) opens} + * the packages described by its {@link ModuleDescriptor}. Qualified exports + * (where a package is exported to a set of target modules rather than all + * modules) are reified when creating the layer as follows:

+ * + * + *

Qualified opens are handled in same way as qualified exports.

+ * *

As when creating a {@code Configuration}, * {@link ModuleDescriptor#isAutomatic() automatic} modules receive special * treatment when creating a layer. An automatic module is created in the @@ -193,7 +213,7 @@ } private void ensureInLayer(Module source) { - if (!layer.modules().contains(source)) + if (source.getLayer() != layer) throw new IllegalArgumentException(source + " not in layer"); } @@ -220,9 +240,8 @@ * @see Module#addReads */ public Controller addReads(Module source, Module target) { - Objects.requireNonNull(source); - Objects.requireNonNull(target); ensureInLayer(source); + Objects.requireNonNull(target); Modules.addReads(source, target); return this; } @@ -248,9 +267,9 @@ * @see Module#addOpens */ public Controller addOpens(Module source, String pn, Module target) { - Objects.requireNonNull(source); - Objects.requireNonNull(target); ensureInLayer(source); + Objects.requireNonNull(pn); + Objects.requireNonNull(target); Modules.addOpens(source, pn, target); return this; } @@ -408,8 +427,8 @@ * * *

In addition, a layer cannot be created if the configuration contains - * a module named "{@code java.base}" or a module with a package name - * starting with "{@code java.}".

+ * a module named "{@code java.base}", or a module contains a package named + * "{@code java}" or a package with a name starting with "{@code java.}".

* *

If there is a security manager then the class loader created by * this method will load classes and resources with privileges that are @@ -418,7 +437,7 @@ * @param cf * The configuration for the layer * @param parentLayers - * The list parent layers in search order + * The list of parent layers in search order * @param parentLoader * The parent class loader for the class loader created by this * method; may be {@code null} for the bootstrap class loader @@ -485,7 +504,7 @@ * @param cf * The configuration for the layer * @param parentLayers - * The list parent layers in search order + * The list of parent layers in search order * @param parentLoader * The parent class loader for each of the class loaders created by * this method; may be {@code null} for the bootstrap class loader @@ -497,8 +516,10 @@ * the parent layers, including order * @throws LayerInstantiationException * If the layer cannot be created because the configuration contains - * a module named "{@code java.base}" or a module with a package - * name starting with "{@code java.}" + * a module named "{@code java.base}" or a module contains a package + * named "{@code java}" or a package with a name starting with + * "{@code java.}" + * * @throws SecurityException * If {@code RuntimePermission("createClassLoader")} or * {@code RuntimePermission("getClassLoader")} is denied by @@ -558,10 +579,11 @@ * *

In addition, a layer cannot be created if the configuration contains * a module named "{@code java.base}", a configuration contains a module - * with a package name starting with "{@code java.}" is mapped to a class - * loader other than the {@link ClassLoader#getPlatformClassLoader() - * platform class loader}, or the function to map a module name to a class - * loader returns {@code null}.

+ * with a package named "{@code java}" or a package name starting with + * "{@code java.}" and the module is mapped to a class loader other than + * the {@link ClassLoader#getPlatformClassLoader() platform class loader}, + * or the function to map a module name to a class loader returns + * {@code null}.

* *

If the function to map a module name to class loader throws an error * or runtime exception then it is propagated to the caller of this method. @@ -575,7 +597,7 @@ * @param cf * The configuration for the layer * @param parentLayers - * The list parent layers in search order + * The list of parent layers in search order * @param clf * The function to map a module name to a class loader * @@ -754,10 +776,16 @@ * @return A possibly-empty unmodifiable set of the modules in this layer */ public Set modules() { - return Collections.unmodifiableSet( - nameToModule.values().stream().collect(Collectors.toSet())); + Set modules = this.modules; + if (modules == null) { + this.modules = modules = + Collections.unmodifiableSet(new HashSet<>(nameToModule.values())); + } + return modules; } + private volatile Set modules; + /** * Returns the module with the given name in this layer, or if not in this @@ -776,6 +804,8 @@ */ public Optional findModule(String name) { Objects.requireNonNull(name); + if (this == EMPTY_LAYER) + return Optional.empty(); Module m = nameToModule.get(name); if (m != null) return Optional.of(m);