< prev index next >
src/java.base/share/classes/java/lang/reflect/Layer.java
Print this page
*** 64,76 ****
*
* <p> Creating a layer creates a {@link Module} object for each {@link
* 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}. </p>
*
* <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
* {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
* provide convenient ways to create a {@code Layer} where all modules are
* mapped to a single class loader or where each module is mapped to its own
--- 64,74 ----
*
* <p> Creating a layer creates a {@link Module} object for each {@link
* 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. </p>
*
* <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
* {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
* provide convenient ways to create a {@code Layer} where all modules are
* mapped to a single class loader or where each module is mapped to its own
*** 89,98 ****
--- 87,118 ----
* The modules in the boot layer are mapped to the bootstrap class loader and
* other class loaders that are <a href="../ClassLoader.html#builtinLoaders">
* built-in</a> into the Java virtual machine. The boot layer will often be
* the {@link #parents() parent} when creating additional layers. </p>
*
+ * <p> 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: </p>
+ * <ul>
+ * <li> If module {@code X} exports a package to {@code Y}, and if the
+ * runtime {@code Module} {@code X} reads {@code Module} {@code Y}, then
+ * the package is exported to {@code Module} {@code Y} (which may be in
+ * the same layer as {@code X} or a parent layer). </li>
+ *
+ * <li> If module {@code X} exports a package to {@code Y}, and if the
+ * runtime {@code Module} {@code X} does not read {@code Y} then target
+ * {@code Y} is located as if by invoking {@link #findModule(String)
+ * findModule} to find the module in the layer or its parent layers. If
+ * {@code Y} is found then the package is exported to the instance of
+ * {@code Y} that was found. If {@code Y} is not found then the qualified
+ * export is ignored. </li>
+ * </ul>
+ *
+ * <p> Qualified opens are handled in same way as qualified exports. </p>
+ *
* <p> 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
* Java virtual machine as a {@code Module} that reads every unnamed {@code
* Module} in the Java virtual machine. </p>
*** 191,201 ****
public Layer layer() {
return layer;
}
private void ensureInLayer(Module source) {
! if (!layer.modules().contains(source))
throw new IllegalArgumentException(source + " not in layer");
}
/**
--- 211,221 ----
public Layer layer() {
return layer;
}
private void ensureInLayer(Module source) {
! if (source.getLayer() != layer)
throw new IllegalArgumentException(source + " not in layer");
}
/**
*** 218,230 ****
* If {@code source} is not in the layer
*
* @see Module#addReads
*/
public Controller addReads(Module source, Module target) {
- Objects.requireNonNull(source);
- Objects.requireNonNull(target);
ensureInLayer(source);
Modules.addReads(source, target);
return this;
}
/**
--- 238,249 ----
* If {@code source} is not in the layer
*
* @see Module#addReads
*/
public Controller addReads(Module source, Module target) {
ensureInLayer(source);
+ Objects.requireNonNull(target);
Modules.addReads(source, target);
return this;
}
/**
*** 246,258 ****
* in the source module
*
* @see Module#addOpens
*/
public Controller addOpens(Module source, String pn, Module target) {
- Objects.requireNonNull(source);
- Objects.requireNonNull(target);
ensureInLayer(source);
Modules.addOpens(source, pn, target);
return this;
}
}
--- 265,277 ----
* in the source module
*
* @see Module#addOpens
*/
public Controller addOpens(Module source, String pn, Module target) {
ensureInLayer(source);
+ Objects.requireNonNull(pn);
+ Objects.requireNonNull(target);
Modules.addOpens(source, pn, target);
return this;
}
}
*** 406,426 ****
* in a specific package. </p></li>
*
* </ul>
*
* <p> 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.}". </p>
*
* <p> If there is a security manager then the class loader created by
* this method will load classes and resources with privileges that are
* restricted by the calling context of this method. </p>
*
* @param cf
* The configuration for the layer
* @param parentLayers
! * The list 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
*
* @return A controller that controls the newly created layer
--- 425,445 ----
* in a specific package. </p></li>
*
* </ul>
*
* <p> In addition, a layer cannot be created if the configuration contains
! * 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.}". </p>
*
* <p> If there is a security manager then the class loader created by
* this method will load classes and resources with privileges that are
* restricted by the calling context of this method. </p>
*
* @param cf
* The configuration for the layer
* @param parentLayers
! * 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
*
* @return A controller that controls the newly created layer
*** 483,493 ****
* restricted by the calling context of this method. </p>
*
* @param cf
* The configuration for the layer
* @param parentLayers
! * The list 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
*
* @return A controller that controls the newly created layer
--- 502,512 ----
* restricted by the calling context of this method. </p>
*
* @param cf
* The configuration for the layer
* @param parentLayers
! * 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
*
* @return A controller that controls the newly created layer
*** 495,506 ****
* @throws IllegalArgumentException
* If the parent configurations do not match the configuration of
* 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.}"
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
*
--- 514,527 ----
* @throws IllegalArgumentException
* If the parent configurations do not match the configuration of
* 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 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
* the security manager
*
*** 556,569 ****
*
* </ul>
*
* <p> 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}. </p>
*
* <p> 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.
* </p>
*
--- 577,591 ----
*
* </ul>
*
* <p> 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 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}. </p>
*
* <p> 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.
* </p>
*
*** 573,583 ****
* to the Java virtual machine.
*
* @param cf
* The configuration for the layer
* @param parentLayers
! * The list parent layers in search order
* @param clf
* The function to map a module name to a class loader
*
* @return A controller that controls the newly created layer
*
--- 595,605 ----
* to the Java virtual machine.
*
* @param cf
* The configuration for the layer
* @param parentLayers
! * The list of parent layers in search order
* @param clf
* The function to map a module name to a class loader
*
* @return A controller that controls the newly created layer
*
*** 752,764 ****
* Returns the set of the modules in this layer.
*
* @return A possibly-empty unmodifiable set of the modules in this layer
*/
public Set<Module> modules() {
! return Collections.unmodifiableSet(
! nameToModule.values().stream().collect(Collectors.toSet()));
}
/**
* Returns the module with the given name in this layer, or if not in this
* layer, the {@linkplain #parents parent} layers. Finding a module in
--- 774,792 ----
* Returns the set of the modules in this layer.
*
* @return A possibly-empty unmodifiable set of the modules in this layer
*/
public Set<Module> modules() {
! Set<Module> modules = this.modules;
! if (modules == null) {
! this.modules = modules =
! Collections.unmodifiableSet(new HashSet<>(nameToModule.values()));
}
+ return modules;
+ }
+
+ private volatile Set<Module> modules;
/**
* Returns the module with the given name in this layer, or if not in this
* layer, the {@linkplain #parents parent} layers. Finding a module in
*** 774,783 ****
--- 802,813 ----
* if there isn't a module with this name in this layer or any
* parent layer
*/
public Optional<Module> 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);
return layers()
< prev index next >