/*
* Copyright (c) 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
Classes to support module descriptors and creating configurations of modules
by means of resolution and service binding.
Unless otherwise noted, passing a null
argument to a constructor or method of any class or interface in this package will cause a NullPointerException
to be thrown. Additionally, invoking a method with an array or collection containing a null
element will cause a NullPointerException
, unless otherwise specified.
Resolution
Resolution is the process of computing how modules depend on each other.
The process occurs at compile time and run time.
Resolution is a two-step process. The first step recursively enumerates
the 'requires' directives of a set of root modules. If all the enumerated
modules are observable, then the second step computes their readability graph.
The readability graph embodies how modules depend on each other, which in
turn controls access across module boundaries.
Step 1: Recursive enumeration
Recursive enumeration takes a set of module names, looks up each of their
module declarations, and for each module declaration, recursively enumerates:
-
the module names given by the 'requires' directives with the
'transitive' modifier, and
-
at the discretion of the host system, the module names given by
the 'requires' directives without the 'transitive' modifier.
Module declarations are looked up in a set of observable modules. The set of observable modules is determined in an implementation specific manner. The set of observable modules may include modules with explicit declarations (that is, with a module-info.java
source file or module-info.class
file) and modules with implicit declarations (that is, automatic modules).
Because an automatic module has no explicit module declaration, it has no
'requires' directives of its own, although its name may be given by a
'requires' directive of an explicit module declaration.
The set of root modules, whose names are the initial input to this
algorithm, is determined in an implementation specific manner. The set of
root modules may include automatic modules.
If at least one automatic module is enumerated by this algorithm, then
every observable automatic module must be enumerated, regardless of whether
any of their names are given by 'requires' directives of explicit module
declarations.
If any of the following conditions occur, then resolution fails:
Any root module is not observable.
Any module whose name is given by a 'requires' directive with the
'transitive' modifier is not observable.
At the discretion of the host system, any module whose name is given
by a 'requires' directive without the 'transitive' modifier is not
observable.
The algorithm in this step enumerates the same module name twice. This
indicates a cycle in the 'requires' directives, disregarding any 'transitive'
modifiers.
Otherwise, resolution proceeds to step 2.
Step 2: Computing the readability graph
A 'requires' directive (irrespective of 'transitive') expresses that
one module depends on some other module. The effect of the 'transitive'
modifier is to cause additional modules to also depend on the other module.
If module M 'requires transitive N', then not only does M depend on N, but
any module that depends on M also depends on N. This allows M to be
refactored so that some or all of its content can be moved to a new module N
without breaking modules that have a 'requires M' directive.
Module dependencies are represented by the readability graph. The
readability graph is a directed graph whose vertices are the modules
enumerated in step 1 and whose edges represent readability between pairs of
modules. The edges are specified as follows:
First, readability is determined by the 'requires' directives of the
enumerated modules, disregarding any 'transitive' modifiers:
For each enumerated module A that 'requires' B: A "reads" B.
For each enumerated module X that is automatic: X "reads" every
other enumerated module (it is "as if" an automatic module has 'requires'
directives for every other enumerated module).
Second, readability is augmented to account for 'transitive' modifiers:
-
For each enumerated module A that "reads" B:
If B 'requires transitive' C, then A "reads" C as well as B. This
augmentation is recursive: since A "reads" C, if C 'requires transitive'
D, then A "reads" D as well as C and B.
If B is an automatic module, then A "reads" every other enumerated
automatic module. (It is "as if" an automatic module has 'requires transitive'
directives for every other enumerated automatic module).
Finally, every module "reads" itself.
If any of the following conditions occur in the readability graph, then
resolution fails:
A module "reads" two or more modules with the same name. This includes
the case where a module "reads" another with the same name as itself.
Two or more modules export a package with the same name to a module
that "reads" both. This includes the case where a module M containing package
p "reads" another module that exports p to M.
A module M declares that it 'uses p.S' or 'provides p.S with ...' but
package p is neither in module M nor exported to M by any module that M
"reads".
Otherwise, resolution succeeds, and the result of resolution is the
readability graph.
Root modules
The set of root modules at compile-time is usually the set of modules
being compiled. At run-time, the set of root modules is usually the
application module specified to the 'java' launcher. When compiling code in
the unnamed module, or at run-time when the main application class is loaded
from the class path, then the default set of root modules is implementation
specific (In the JDK implementation it is the module "java.se", if observable,
and every observable module that exports an API).
Observable modules
The set of observable modules at both compile-time and run-time is
determined by searching several different paths, and also by searching
the compiled modules built in to the environment. The search order is as
follows:
At compile time only, the compilation module path. This path
contains module definitions in source form.
The upgrade module path. This path contains compiled definitions of
modules that will be observed in preference to the compiled definitions of
any upgradeable modules that are present in (3) and (4). See the Java
SE Platform for the designation of which standard modules are upgradeable.
The system modules, which are the compiled definitions built in to
the environment.
The application module path. This path contains compiled definitions
of library and application modules.
'requires' directives with 'static' modifier
'requires' directives that have the 'static' modifier express an optional
dependence at run time. If a module declares that it 'requires static M' then
resolution does not search the observable modules for M to satisfy the dependency.
However, if M is recursively enumerated at step 1 then all modules that are
enumerated and `requires static M` will read M.
Completeness
Resolution may be partial at compile-time in that the complete transitive
closure may not be required to compile a set of modules. Minimally, the
readability graph that is constructed and validated at compile-time includes
the modules being compiled, their direct dependences, and all implicitly
declared dependences (requires transitive).
At run-time, resolution is an additive process. The recursive enumeration
at step 1 may be relative to previous resolutions so that a root module,
or a module named in a 'requires' directive, is not enumerated when it was
enumerated by a previous (or parent) resolution. The readability graph that
is the result of resolution may therefore have a vertex for a module enumerated
in step 1 but with an edge to represent that the module reads a module that
was enumerated by previous (or parent) resolution.
Since: 9 @spec JPMS
/**
* Classes to support module descriptors and creating configurations of modules
* by means of resolution and service binding.
*
* <p> Unless otherwise noted, passing a {@code null} argument to a constructor
* or method of any class or interface in this package will cause a {@link
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
* invoking a method with an array or collection containing a {@code null} element
* will cause a {@code NullPointerException}, unless otherwise specified. </p>
*
*
* <h1><a id="resolution">Resolution</a></h1>
*
* <p> Resolution is the process of computing how modules depend on each other.
* The process occurs at compile time and run time. </p>
*
* <p> Resolution is a two-step process. The first step recursively enumerates
* the 'requires' directives of a set of root modules. If all the enumerated
* modules are observable, then the second step computes their readability graph.
* The readability graph embodies how modules depend on each other, which in
* turn controls access across module boundaries. </p>
*
* <h2> Step 1: Recursive enumeration </h2>
*
* <p> Recursive enumeration takes a set of module names, looks up each of their
* module declarations, and for each module declaration, recursively enumerates:
*
* <ul>
* <li> <p> the module names given by the 'requires' directives with the
* 'transitive' modifier, and </p></li>
* <li> <p> at the discretion of the host system, the module names given by
* the 'requires' directives without the 'transitive' modifier. </p></li>
* </ul>
*
* <p> Module declarations are looked up in a set of observable modules. The set
* of observable modules is determined in an implementation specific manner. The
* set of observable modules may include modules with explicit declarations
* (that is, with a {@code module-info.java} source file or {@code module-info.class}
* file) and modules with implicit declarations (that is,
* <a href="ModuleFinder.html#automatic-modules">automatic modules</a>).
* Because an automatic module has no explicit module declaration, it has no
* 'requires' directives of its own, although its name may be given by a
* 'requires' directive of an explicit module declaration. </p>
* <p> The set of root modules, whose names are the initial input to this
* algorithm, is determined in an implementation specific manner. The set of
* root modules may include automatic modules. </p>
*
* <p> If at least one automatic module is enumerated by this algorithm, then
* every observable automatic module must be enumerated, regardless of whether
* any of their names are given by 'requires' directives of explicit module
* declarations. </p>
*
* <p> If any of the following conditions occur, then resolution fails:
* <ul>
* <li><p> Any root module is not observable. </p></li>
* <li><p> Any module whose name is given by a 'requires' directive with the
* 'transitive' modifier is not observable. </p></li>
* <li><p> At the discretion of the host system, any module whose name is given
* by a 'requires' directive without the 'transitive' modifier is not
* observable. </p></li>
* <li><p> The algorithm in this step enumerates the same module name twice. This
* indicates a cycle in the 'requires' directives, disregarding any 'transitive'
* modifiers. </p></li>
* </ul>
*
* <p> Otherwise, resolution proceeds to step 2. </p>
*
* <h2> Step 2: Computing the readability graph </h2>
*
* <p> A 'requires' directive (irrespective of 'transitive') expresses that
* one module depends on some other module. The effect of the 'transitive'
* modifier is to cause additional modules to also depend on the other module.
* If module M 'requires transitive N', then not only does M depend on N, but
* any module that depends on M also depends on N. This allows M to be
* refactored so that some or all of its content can be moved to a new module N
* without breaking modules that have a 'requires M' directive. </p>
*
* <p> Module dependencies are represented by the readability graph. The
* readability graph is a directed graph whose vertices are the modules
* enumerated in step 1 and whose edges represent readability between pairs of
* modules. The edges are specified as follows:
*
* <p> First, readability is determined by the 'requires' directives of the
* enumerated modules, disregarding any 'transitive' modifiers:
*
* <ul>
* <li><p> For each enumerated module A that 'requires' B: A "reads" B. </p></li>
* <li><p> For each enumerated module X that is automatic: X "reads" every
* other enumerated module (it is "as if" an automatic module has 'requires'
* directives for every other enumerated module). </p></li>
* </ul>
*
* <p> Second, readability is augmented to account for 'transitive' modifiers:
* <ul>
* <li> <p> For each enumerated module A that "reads" B: </p>
* <ul>
* <li><p> If B 'requires transitive' C, then A "reads" C as well as B. This
* augmentation is recursive: since A "reads" C, if C 'requires transitive'
* D, then A "reads" D as well as C and B. </p></li>
* <li><p> If B is an automatic module, then A "reads" every other enumerated
* automatic module. (It is "as if" an automatic module has 'requires transitive'
* directives for every other enumerated automatic module).</p> </li>
* </ul>
* </li>
* </ul>
*
* <p> Finally, every module "reads" itself. </p>
*
* <p> If any of the following conditions occur in the readability graph, then
* resolution fails:
* <ul>
* <li><p> A module "reads" two or more modules with the same name. This includes
* the case where a module "reads" another with the same name as itself. </p></li>
* <li><p> Two or more modules export a package with the same name to a module
* that "reads" both. This includes the case where a module M containing package
* p "reads" another module that exports p to M. </p></li>
* <li><p> A module M declares that it 'uses p.S' or 'provides p.S with ...' but
* package p is neither in module M nor exported to M by any module that M
* "reads". </p></li>
* </ul>
* <p> Otherwise, resolution succeeds, and the result of resolution is the
* readability graph.
*
* <h2> Root modules </h2>
*
* <p> The set of root modules at compile-time is usually the set of modules
* being compiled. At run-time, the set of root modules is usually the
* application module specified to the 'java' launcher. When compiling code in
* the unnamed module, or at run-time when the main application class is loaded
* from the class path, then the default set of root modules is implementation
* specific (In the JDK implementation it is the module "java.se", if observable,
* and every observable module that exports an API). </p>
*
* <h2> Observable modules </h2>
*
* <p> The set of observable modules at both compile-time and run-time is
* determined by searching several different paths, and also by searching
* the compiled modules built in to the environment. The search order is as
* follows: </p>
*
* <ol>
* <li><p> At compile time only, the compilation module path. This path
* contains module definitions in source form. </p></li>
*
* <li><p> The upgrade module path. This path contains compiled definitions of
* modules that will be observed in preference to the compiled definitions of
* any <i>upgradeable modules</i> that are present in (3) and (4). See the Java
* SE Platform for the designation of which standard modules are upgradeable.
* </p></li>
*
* <li><p> The system modules, which are the compiled definitions built in to
* the environment. </p></li>
*
* <li><p> The application module path. This path contains compiled definitions
* of library and application modules. </p></li>
*
* </ol>
*
* <h2> 'requires' directives with 'static' modifier </h2>
*
* <p> 'requires' directives that have the 'static' modifier express an optional
* dependence at run time. If a module declares that it 'requires static M' then
* resolution does not search the observable modules for M to satisfy the dependency.
* However, if M is recursively enumerated at step 1 then all modules that are
* enumerated and `requires static M` will read M. </p>
*
* <h2> Completeness </h2>
*
* <p> Resolution may be partial at compile-time in that the complete transitive
* closure may not be required to compile a set of modules. Minimally, the
* readability graph that is constructed and validated at compile-time includes
* the modules being compiled, their direct dependences, and all implicitly
* declared dependences (requires transitive). </p>
*
* <p> At run-time, resolution is an additive process. The recursive enumeration
* at step 1 may be relative to previous resolutions so that a root module,
* or a module named in a 'requires' directive, is not enumerated when it was
* enumerated by a previous (or parent) resolution. The readability graph that
* is the result of resolution may therefore have a vertex for a module enumerated
* in step 1 but with an edge to represent that the module reads a module that
* was enumerated by previous (or parent) resolution. </p>
*
* @since 9
* @spec JPMS
*/
package java.lang.module;