--- old/src/java.base/share/classes/java/lang/module/Configuration.java 2017-02-07 13:13:25.967732046 +0000 +++ new/src/java.base/share/classes/java/lang/module/Configuration.java 2017-02-07 13:13:25.799720508 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, 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 @@ -42,126 +42,48 @@ import java.util.stream.Stream; /** - * The configuration that is the result of resolution or resolution with - * service binding. - * - *
Resolution is the process of computing the transitive closure of a set - * of root modules over a set of observable modules by resolving the - * dependences expressed by {@code requires} clauses. - * - * The dependence graph is augmented with edges that take account of - * implicitly declared dependences ({@code requires transitive}) to create a - * readability graph. A {@code Configuration} encapsulates the - * resulting graph of {@link ResolvedModule resolved modules}. - * - *
Suppose we have the following observable modules:
- *{@code - * module m1 { requires m2; } - * module m2 { requires transitive m3; } - * module m3 { } - * module m4 { } - * }- * - *
If the module {@code m1} is resolved then the resulting configuration - * contains three modules ({@code m1}, {@code m2}, {@code m3}). The edges in - * its readability graph are:
- *{@code - * m1 --> m2 (meaning m1 reads m2) - * m1 --> m3 - * m2 --> m3 - * }- * - *
Resolution is an additive process. When computing the transitive closure - * then the dependence relation may include dependences on modules in parent - * configurations. The result is a relative configuration that is - * relative to one or more parent configurations and where the readability graph - * may have edges from modules in the configuration to modules in parent - * configurations. - * - *
- * - *Suppose we have the following observable modules:
- *{@code - * module m1 { requires m2; requires java.xml; } - * module m2 { } - * }- * - *
If module {@code m1} is resolved with the configuration for the {@link - * java.lang.reflect.Layer#boot() boot} layer as the parent then the resulting - * configuration contains two modules ({@code m1}, {@code m2}). The edges in - * its readability graph are: - *
{@code - * m1 --> m2 - * m1 --> java.xml - * }- * where module {@code java.xml} is in the parent configuration. For - * simplicity, this example omits the implicitly declared dependence on the - * {@code java.base} module. - * - * - *
{@link ModuleDescriptor#isAutomatic() Automatic} modules receive special - * treatment during resolution. Each automatic module is resolved so that it - * reads all other modules in the configuration and all parent configurations. - * Each automatic module is also resolved as if it {@code requires transitive} - * all other automatic modules in the configuration (and all automatic modules - * in parent configurations).
- - *Service binding is the process of augmenting a graph of resolved modules - * from the set of observable modules induced by the service-use dependence - * ({@code uses} and {@code provides} clauses). Any module that was not - * previously in the graph requires resolution to compute its transitive - * closure. Service binding is an iterative process in that adding a module - * that satisfies some service-use dependence may introduce new service-use - * dependences.
- * - *Suppose we have the following observable modules:
- *{@code - * module m1 { exports p; uses p.S; } - * module m2 { requires m1; provides p.S with p2.S2; } - * module m3 { requires m1; requires m4; provides p.S with p3.S3; } - * module m4 { } - * }- * - *
If the module {@code m1} is resolved then the resulting graph of modules - * has one module ({@code m1}). If the graph is augmented with modules induced - * by the service-use dependence relation then the configuration will contain - * four modules ({@code m1}, {@code m2}, {@code m3}, {@code m4}). The edges in - * its readability graph are:
- *{@code - * m2 --> m1 - * m3 --> m1 - * m3 --> m4 - * }- *
The edges in the conceptual service-use graph are:
- *{@code - * m1 --> m2 (meaning m1 uses a service that is provided by m2) - * m1 --> m3 - * }- * - *
If this configuration is instantiated as a {@code Layer}, and if code in - * module {@code m1} uses {@link java.util.ServiceLoader ServiceLoader} to - * iterate over implementations of {@code p.S.class}, then it will iterate over - * an instance of {@code p2.S2} and {@code p3.S3}.
+ * A configuration that is the result of + * resolution or resolution with + * service binding. + * + *A configuration encapsulates the readability graph that is the + * output of resolution. A readability graph is a directed graph where the nodes + * are of type {@link ResolvedModule} and the edges represent the readability + * amongst the modules. {@code Configuration} defines the {@link #modules() + * modules()} method to get the set of resolved modules in the graph. {@code + * ResolvedModule} defines the {@link ResolvedModule#reads() reads()} method to + * get the set of modules that a resolved module reads. The modules that are + * read may be in the same configuration or may be in {@link #parents() parent} + * configurations.
+ * + *Configuration defines the {@link #resolve(ModuleFinder,List,ModuleFinder,Collection) + * resolve} method to resolve a collection of root modules, and the {@link + * #resolveAndBind(ModuleFinder,List,ModuleFinder,Collection) resolveAndBind} + * method to do resolution with service binding. There are instance and + * static variants of both methods. The instance methods create a configuration + * with the receiver as the parent configuration. The static methods are for + * more advanced cases where there can be more than one parent configuration.
+ * + *Each {@link java.lang.reflect.Layer layer} of modules in the Java virtual + * machine is created from a configuration. The configuration for the {@link + * java.lang.reflect.Layer#boot() boot} layer is obtained by invoking {@code + * Layer.boot().configuration()}. The configuration for the boot layer will + * often be the parent when creating new configurations.
* *The following example uses the {@code resolveRequires} method to resolve - * a module named myapp with the configuration for the boot layer as - * the parent configuration. It prints the name of each resolved module and - * the names of the modules that each module reads.
+ *The following example uses the {@link + * #resolve(ModuleFinder,ModuleFinder,Collection) resolve} method to resolve a + * module named myapp with the configuration for the boot layer as the + * parent configuration. It prints the name of each resolved module and the + * names of the modules that each module reads.
* *{@code * ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3); * * Configuration parent = Layer.boot().configuration(); * - * Configuration cf = parent.resolveRequires(finder, - * ModuleFinder.of(), - * Set.of("myapp")); + * Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("myapp")); * cf.modules().forEach(m -> { * System.out.format("%s -> %s%n", * m.name(), @@ -172,6 +94,7 @@ * }* * @since 9 + * @spec JPMS * @see java.lang.reflect.Layer */ public final class Configuration { @@ -186,11 +109,23 @@ private final Set
{@code - * Configuration.resolveRequires(before, List.of(cf), after, roots); + * Configuration.resolve(before, List.of(cf), after, roots); * }* * @param before * The before module finder to find modules * @param after - * The after module finder to locate modules when a - * module cannot be located by the {@code before} module finder - * and the module is not in this configuration + * The after module finder to locate modules when not + * located by the {@code before} module finder or in parent + * configurations * @param roots * The possibly-empty collection of module names of the modules * to resolve @@ -242,16 +180,20 @@ * @return The configuration that is the result of resolving the given * root modules * + * @throws FindException + * If resolution fails for any of the observability-related reasons + * specified by the static {@code resolve} method * @throws ResolutionException - * If resolution or the post-resolution checks fail + * If any of the post-resolution consistency checks specified by + * the static {@code resolve} method fail * @throws SecurityException * If locating a module is denied by the security manager */ - public Configuration resolveRequires(ModuleFinder before, - ModuleFinder after, - Collection
{@code - * Configuration.resolveRequiresAndUses(before, List.of(cf), after, roots); + * Configuration.resolveAndBind(before, List.of(cf), after, roots); * }* * @@ -272,25 +214,29 @@ * The before module finder to find modules * @param after * The after module finder to locate modules when not - * located by the {@code before} module finder and this - * configuration + * located by the {@code before} module finder or in parent + * configurations * @param roots * The possibly-empty collection of module names of the modules * to resolve * - * @return The configuration that is the result of resolving the given - * root modules + * @return The configuration that is the result of resolving, with service + * binding, the given root modules * + * @throws FindException + * If resolution fails for any of the observability-related reasons + * specified by the static {@code resolve} method * @throws ResolutionException - * If resolution or the post-resolution checks fail + * If any of the post-resolution consistency checks specified by + * the static {@code resolve} method fail * @throws SecurityException * If locating a module is denied by the security manager */ - public Configuration resolveRequiresAndUses(ModuleFinder before, - ModuleFinder after, - Collection
When all modules have been resolved then the resulting dependency * graph is checked to ensure that it does not contain cycles. A - * readability graph is constructed and in conjunction with the module + * readability graph is constructed, and in conjunction with the module * exports and service use, checked for consistency.
* - *Resolution and the (post-resolution) consistency checks may fail for - * following reasons:
+ *Resolution may fail with {@code FindException} for the following + * observability-related reasons:
* *A root module, or a direct or transitive dependency, is not @@ -343,6 +289,20 @@ * descriptor ({@code module-info.class}) or two versions of the same * module are found in the same directory.
A module with the required name is found but the module + * requires a different {@link ModuleDescriptor#osName() operating + * system}, {@link ModuleDescriptor#osArch() architecture}, or {@link + * ModuleDescriptor#osVersion() version} to other modules that have + * been resolved for the new configuration or modules in the parent + * configurations.
Post-resolution consistency checks may fail with {@code + * ResolutionException} for the following reasons:
+ * + *A cycle is detected, say where module {@code m1} requires * module {@code m2} and {@code m2} requires {@code m1}.
A module {@code M} declares that it - * "{@code provides ... with q.T}" but package {@code q} is not in - * module {@code M}.
Two or more modules in the configuration are specific to - * different {@link ModuleDescriptor#osName() operating systems}, - * {@link ModuleDescriptor#osArch() architectures}, or {@link - * ModuleDescriptor#osVersion() versions}.
Other implementation specific checks, for example referential - * integrity checks to ensure that different versions of tighly coupled - * modules cannot be combined in the same configuration.
This method works exactly as specified by {@link - * #resolveRequires(ModuleFinder,List,ModuleFinder,Collection) - * resolveRequires} except that the graph of resolved modules is augmented + * #resolve(ModuleFinder,List,ModuleFinder,Collection) + * resolve} except that the graph of resolved modules is augmented * with modules induced by the service-use dependence relation.
* *More specifically, the root modules are resolved as if by calling - * {@code resolveRequires}. The resolved modules, and all modules in the + * {@code resolve}. The resolved modules, and all modules in the * parent configurations, with {@link ModuleDescriptor#uses() service * dependences} are then examined. All modules found by the given module * finders that {@link ModuleDescriptor#provides() provide} an * implementation of one or more of the service types are added to the * module graph and then resolved as if by calling the {@code - * resolveRequires} method. Adding modules to the module graph may - * introduce new service-use dependences and so the process works - * iteratively until no more modules are added.
- * - *As service binding involves resolution then it may fail with {@link - * ResolutionException} for exactly the same reasons specified in - * {@code resolveRequires}.
+ * resolve} method. Adding modules to the module graph may introduce new + * service-use dependences and so the process works iteratively until no + * more modules are added. + * + *As service binding involves resolution then it may fail with {@code + * FindException} or {@code ResolutionException} for exactly the same + * reasons specified in {@code resolve}.
* * @param before * The before module finder to find modules @@ -448,20 +404,26 @@ * The possibly-empty collection of module names of the modules * to resolve * - * @return The configuration that is the result of resolving the given - * root modules + * @return The configuration that is the result of resolving, with service + * binding, the given root modules * + * @throws FindException + * If resolution fails for any of the observability-related reasons + * specified by the static {@code resolve} method * @throws ResolutionException - * If resolution or the post-resolution checks fail + * If any of the post-resolution consistency checks specified by + * the static {@code resolve} method fail * @throws IllegalArgumentException - * If the list of parents is empty + * If the list of parents is empty, or the list has two or more + * parents with modules for different target operating systems, + * architectures, or versions * @throws SecurityException * If locating a module is denied by the security manager */ - public static Configuration resolveRequiresAndUses(ModuleFinder before, - List