JDK-8061972 : JEP 261: Module System
  • Type: JEP
  • Component: not defined
  • Priority: P1
  • Status: Closed
  • Resolution: Delivered
  • Fix Versions: 9
  • Submitted: 2014-10-23
  • Updated: 2024-08-19
  • Resolved: 2017-09-21
Related Reports
Blocks :  
Blocks :  
Blocks :  
Blocks :  
Relates :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8169849 :  
Description
Summary
-------

Implement the Java Platform Module System, as specified by
[JSR 376][jpms], together with related JDK-specific changes and
enhancements.

[jpms]: http://openjdk.java.net/projects/jigsaw/spec/


Description
-----------

The [Java Platform Module System (JSR 376)][jpms] specifies changes and
extensions to the Java programming language, the Java virtual machine,
and the standard Java APIs.  This JEP implements that specification.  As
a consequence, the `javac` compiler, the HotSpot virtual machine, and the
run-time libraries implement modules as a fundamental new kind of Java
program component and provide for the reliable configuration and strong
encapsulation of modules in all phases of development.

This JEP also changes, extends, and adds JDK-specific tools and APIs,
which are outside the scope of the JSR, that are related to compilation,
linking, and execution.  Related changes to other tools and APIs, _e.g._,
the `javadoc` tool and the Doclet API, are the subject of separate JEPs.

This JEP assumes that the reader is familiar with the latest
[_State of the Module System_][sotms] document and also the other
[Project Jigsaw][jig] JEPs:

  - [200: The Modular JDK][jep200]
  - [201: Modular Source Code][jep201]
  - [220: Modular Run-Time Images][jep220]
  - [260: Encapsulate Most Internal APIs][jep260]
  - [282: jlink: The Java Linker][jep282]

[sotms]: http://openjdk.java.net/projects/jigsaw/spec/sotms/
[jig]: http://openjdk.java.net/projects/jigsaw/
[jep200]: http://openjdk.java.net/jeps/200
[jep201]: http://openjdk.java.net/jeps/201
[jep220]: http://openjdk.java.net/jeps/220
[jep260]: http://openjdk.java.net/jeps/260
[jep282]: http://openjdk.java.net/jeps/282


### Phases

To the familiar phases of compile time (the `javac` command) and run time
(the `java` run-time launcher) we add the notion of _link time_, an
optional phase between the two in which a set of modules can be assembled
and optimized into a custom run-time image.  The linking tool, `jlink`,
is the subject of [JEP 282][jep282]; many of the new command-line options
implemented by `javac` and `java` are also implemented by `jlink`.


### Module paths

The `javac`, `jlink`, and `java` commands, as well as several others, now
accept options to specify various [_module paths_][sotms-mp].  A module
path is a sequence, each element of which is either a _module definition_
or a directory containing module definitions.  Each module definition is
either

  - A _module artifact_, _i.e._, a modular JAR file or a JMOD file
    containing a compiled module definition, or else

  - An _exploded-module directory_ whose name is, by convention, the
    module's name and whose content is an "exploded" directory tree
    corresponding to a package hierarchy.

In the latter case the directory tree can be a compiled module
definition, populated with individual class and resource files and a
`module-info.class` file at the root or, at compile time, a source module
definition, populated with individual source files and a
`module-info.java` file at the root.

A module path, like other kinds of paths, is specified by a string of
path names separated by the host platform's path-separator character
(`':'` on most platforms, `';'` on Windows).

Module paths are very different from class paths: Class paths are a means
to locate definitions of individual types and resources, whereas module
paths are a means to locate definitions of whole modules.  Each element
of a class path is a container of type and resource definitions, _i.e._,
either a JAR file or an exploded, package-hierarchical directory tree.
Each element of a module path, by contrast, is a module definition or a
directory which each element in the directory is a module definition,
_i.e._, a container of type and resource definitions, _i.e._, either a
modular JAR file, a JMOD file, or an exploded module directory.

During the resolution process the module system locates a module by
searching along several different paths, dependent upon the phase, and
also by searching the compiled modules built-in to the environment, in
the following order:

  - The _compilation module path_ (specified by the command-line option
    `--module-source-path`) contains module definitions in source form
    (compile time only).

  - The _upgrade module path_ (`--upgrade-module-path`) contains compiled
    definitions of modules intended to be used in preference to the
    compiled definitions of any upgradeable modules present amongst the
    system modules or on the application module path (compile time and
    run time).

  - The _system modules_ are the compiled modules built-in to the
    environment (compile time and run time).  These typically include
    [Java SE and JDK modules][jep200] but, in the case of a custom linked
    image, can also include library and application modules.  At compile
    time the system modules can be overridden via the `--system` option,
    which specifies a JDK image from which to load system modules.

  - The _application module path_ (`--module-path`, or `-p` for short)
    contains compiled definitions of library and application modules (all
    phases).  At link time this path can also contain Java SE and JDK
    modules.

The module definitions present on these paths, together with the system
modules, define the universe of _observable modules_.

[sotms-mp]: http://openjdk.java.net/projects/jigsaw/spec/sotms/#module-paths

When searching a module path for a module of a particular name, the
module system takes the first definition of a module of that name.
Version strings, if present, are ignored; if an element of a module path
contains definitions of multiple modules with the same name then
resolution fails and the compiler, linker, or virtual machine will report
an error and exit.  It is the responsibility of build tools and container
applications to configure module paths so as to avoid version conflicts;
it is [not a goal][novers] of the module system to address the
version-selection problem.

[novers]: http://openjdk.java.net/projects/jigsaw/spec/reqs/#version-selection


### Root modules

<a id="root-modules">The module system constructs a module graph by
resolving the transitive closure of the dependences of a set of _root
modules_ with respect to the set of observable modules.</a>

When the compiler compiles code in the unnamed module, or the `java`
launcher is invoked and the main class of the application is loaded from
the class path into the unnamed module of the application class loader,
then the _default set of root modules for the unnamed module_ is
computed as follows in JDK&nbsp;9:

  - The `java.se` module is a root, if it exists.  If it does not exist
    then every `java.*` module on the upgrade module path or among the
    system modules that exports at least one package, without
    qualification, is a root.

  - Every non-`java.*` module on the upgrade module path or among the
    system modules that exports at least one package, without
    qualification, is also a root.

_Update, June 2018: In JDK&nbsp;11, the default set of root modules for
the unnamed module
[changed](https://bugs.openjdk.org/browse/JDK-8205169).  The default set
is now computed as follows:_

  - _Every module on the upgrade module path or among the system modules
    that exports at least one package, without qualification, is a
    root._

_The `java.se` module still exists in JDK&nbsp;11 and later, but it is
no longer a root._

Otherwise, the default set of root modules depends upon the phase:

  - At compile time it is usually the set of modules being compiled (more
    on this below);

  - At link time it is empty; and

  - At run time it is the application's main module, as specified via the
    `--module` (or `-m` for short) launcher option.

It is occasionally necessary to add modules to the default root set in
order to ensure that specific platform, library, or service-provider
modules will be present in the resulting module graph.  In any phase the
option

    --add-modules <module>(,<module>)*

where `<module>` is a module name, adds the indicated modules to the
default set of root modules.  This option may be used more than once.

<a id="ALL-DEFAULT">As a special case at run time, if `<module>` is
`ALL-DEFAULT` then the default set of root modules for the unnamed
module, as defined above, is added to the root set.</a> This is useful
when the application is a container that hosts other applications which
can, in turn, depend upon modules not required by the container itself.

<a id="ALL-SYSTEM">As a further special case at run time, if `<module>`
is `ALL-SYSTEM` then all system modules are added to the root set,
whether or not they are in the default set.</a> This is sometimes needed
by test harnesses.  This option will cause many modules to be resolved;
in general, `ALL-DEFAULT` should be preferred.

<a id="ALL-MODULE-PATH">As a final special case, at both run time and
link time, if `<module>` is `ALL-MODULE-PATH` then all observable modules
found on the relevant module paths are added to the root set.</a>
`ALL-MODULE-PATH` is valid at both compile time and run time.  This is
provided for use by build tools such as Maven, which already ensure that
all modules on the module path are needed.  It is also a convenient means
to add automatic modules to the root set.


### Limiting the observable modules

It is sometimes useful to limit the observable modules for, _e.g._,
debugging, or to reduce the number of modules resolved when the main
module is the unnamed module defined by the application class loader for
the class path.  The `--limit-modules` option can be used, in any phase,
to do this.  Its syntax is:

    --limit-modules <module>(,<module>)*

where `<module>` is a module name.  The effect of this option is to limit
the observable modules to those in the transitive closure of the named
modules plus the main module, if any, plus any further modules specified
via the `--add-modules` option.

(The transitive closure computed for the interpretation of the
 `--limit-modules` option is a temporary result, used only to compute the
 limited set of observable modules.  The resolver will be invoked again
 in order to compute the actual module graph.)


### Increasing readability

When testing and debugging it is sometimes necessary to arrange for one
module to read some other module, even though the first module does not
depend upon the second via a `requires` clause in its module declaration.
This may be needed to, _e.g._, enable a module under test to access the
test harness itself, or to access libraries related to the harness.  The
`--add-reads` option can be used, at both compile time and run time, to
do this.  Its syntax is:

    --add-reads <source-module>=<target-module>

where `<source-module>` and `<target-module>` are module names.

The `--add-reads` option can be used more than once.  The effect of each
instance is to add a [readability edge][sotms-rd] from the source module
to the target module.  This is, essentially, a command-line form of a
`requires` clause in a module declaration, or an invocation of an
unrestricted form of the `Module::addReads` [method][api-addReads].  As a
consequence, code in the source module will be able to access types in a
package of the target module at both compile time and run time if that
package is exported via an `exports` clause in the source module's
declaration, an invocation of the `Module::addExports`
[method][api-addExports], or an instance of the `--add-exports` option
(defined below).  Such code will, additionally, be able to access types
in a package of the target module at run time if that module is declared
to be open or if that package is opened via an `opens` clause in the
source module's declaration, an invocation of the `Module::addOpens`
[method][api-addOpens], or an instance of the `--add-opens` option (also
defined below).

If, for example, a test harness injects a white-box test class into the
`java.management` module, and that class extends an exported utility
class in the (hypothetical) `testng` module, then the access it requires
can be granted via the option

    --add-reads java.management=testng

As a special case, if the `<target-module>` is `ALL-UNNAMED` then
readability edges will be added from the source module to all present and
future unnamed modules, including that corresponding to the class path.
This allows code in modules to be tested by test frameworks that have
not, themselves, yet been converted to modular form.

[sotms-rd]: http://openjdk.java.net/projects/jigsaw/spec/sotms/#readability
[api-addReads]: http://download.java.net/java/jdk9/docs/api/java/lang/reflect/Module.html#addReads-java.lang.reflect.Module-


### Breaking encapsulation

It is sometimes necessary to violate the access-control boundaries
defined by the module system, and enforced by the compiler and virtual
machine, in order to allow one module to access some of the unexported
types of another module.  This may be desirable in order to, _e.g._,
enable white-box testing of internal types, or to expose unsupported
internal APIs to code that has come to depend upon them.  The
`--add-exports` option can be used, at both compile time and run time, to
do this.  Its syntax is:

    --add-exports <source-module>/<package>=<target-module>(,<target-module>)*

where `<source-module>` and `<target-module>` are module names and
`<package>` is the name of a package.

The `--add-exports` option can be used more than once, but at most once
for any particular combination of source module and package name.  The
effect of each instance is to add a [qualified export][sotms-qe] of the
named package from the source module to the target module.  This is,
essentially, a command-line form of an `exports` clause in a module
declaration, or an invocation of an unrestricted form of the
`Module::addExports` [method][api-addExports].  As a consequence, code
in the target module will be able to access public types in the named
package of the source module if the target module reads the source
module, either via a `requires` clause in its module declaration, an
invocation of the `Module::addReads` method, or an instance of the
`--add-reads` option.

If, for example, the module `jmx.wbtest` contains a white-box test for
the unexported `com.sun.jmx.remote.internal` package of the
`java.management` module, then the access it requires can be granted via
the option

    --add-exports java.management/com.sun.jmx.remote.internal=jmx.wbtest

As a special case, if the `<target-module>` is `ALL-UNNAMED` then the
source package will be exported to all unnamed modules, whether they
exist initially or are created later on.  Thus access to the
`sun.management` package of the `java.management` module can be granted
to all code on the class path via the option

    --add-exports java.management/sun.management=ALL-UNNAMED

The `--add-exports` option enables access to the public types of a
specified package.  It is sometimes necessary to go further and enable
access to all non-public elements via the `setAccessible`
[method][api-setAccessible] of the [core reflection API][api-jlr].  The
`--add-opens` option can be used, at run time, to do this.  It has the
same syntax as the `--add-exports` option:

    --add-opens <source-module>/<package>=<target-module>(,<target-module>)*

where `<source-module>` and `<target-module>` are module names and
`<package>` is the name of a package.

The `--add-opens` option can be used more than once, but at most once for
any particular combination of source module and package name.  The effect
of each instance is to add a qualified open of the named package from the
source module to the target module.  This is, essentially, a command-line
form of an `opens` clause in a module declaration, or an invocation of an
unrestricted form of the `Module::addOpens` [method][api-addOpens].  As a
consequence, code in the target module will be able to use the core
reflection API to access all types, public and otherwise, in the named
package of the source module so long as the target module reads the
source module.

Open packages are indistinguishable from non-exported packages at compile
time, so the `--add-opens` option may not be used in that phase.

> **The `--add-exports` and `--add-opens` options must be used with great
    care.  You can use them to gain access to an internal API of a
    library module, or even of the JDK itself, but you do so at your own
    risk: If that internal API is changed or removed then your library or
    application will fail.**

[sotms-qe]: http://openjdk.java.net/projects/jigsaw/spec/sotms/#qualified-exports
[api-addExports]: http://download.java.net/java/jdk9/docs/api/java/lang/reflect/Module.html#addExports-java.lang.String-java.lang.reflect.Module-
[api-addOpens]: http://download.java.net/java/jdk9/docs/api/java/lang/reflect/Module.html#addOpens-java.lang.String-java.lang.reflect.Module-
[api-jlr]: http://download.java.net/java/jdk9/docs/api/java/lang/reflect/package-summary.html
[api-setAccessible]: http://download.java.net/java/jdk9/docs/api/java/lang/reflect/AccessibleObject.html#setAccessible-boolean-


### Patching module content

When testing and debugging it is sometimes useful to replace selected
class files or resources of specific modules with alternate or
experimental versions, or to provide entirely new class files, resources,
and even packages.  This can be done via the `--patch-module` option, at
both compile time and run time.  Its syntax is:

    --patch-module <module>=<file>(<pathsep><file>)*

where `<module>` is a module name, `<file>` is the filesystem path name
of a module definition, and `<pathsep>` is the host platform's
path-separator character.

The `--patch-module` option can be used more than once, but at most once
for any particular module name.  The effect of each instance is to change
how the module system searches for a type in the specified module.
Before it checks the actual module, whether part of the system or defined
on a module path, it first checks, in order, each module definition
specified to the option.  A patch path names a sequence of module
definitions but it is not a module path, since it has leaky,
class-path-like semantics.  This allows a test harness, _e.g._, to inject
multiple tests into the same package without having to copy all of the
tests into a single directory.

The `--patch-module` option cannot be used to replace `module-info.class`
files.  If a `module-info.class` file is found in a module definition on
a patch path then a warning will be issued and the file will be ignored.

If a package found in a module definition on a patch path is not already
exported or opened by that module then it will, still, not be exported or
opened.  It can be exported or opened explicitly via either the
reflection API or the `--add-exports` or `--add-opens` options.

The `--patch-module` option replaces the `-Xbootclasspath:/p` option,
which has been removed (see below).

> **The `--patch-module` option is intended only for testing and debugging.
    Its use in production settings is strongly discouraged.**


### Compile time

The `javac` compiler implements the options described above, as
applicable to compile time: `--module-source-path`,
`--upgrade-module-path`, `--system`, `--module-path`, `--add-modules`,
`--limit-modules`, `--add-reads`, `--add-exports`, and `--patch-module`.

The compiler operates in one of three modes, each of which implements
additional options.

  - _Legacy mode_ is enabled when the compilation environment, as defined
    by the `-source`, `-target`, and `--release` options, is less than or
    equal to 8.  None of the modular options described above may be used.

In legacy mode the compiler behaves in essentially the same way as it
does in JDK 8.

  - _Single-module mode_ is enabled when the compilation environment is 9
    or later and the `--module-source-path` option is not used.  The
    other modular options described above may be used; the existing
    options `-bootclasspath`, `-Xbootclasspath`, `-extdirs`,
    `-endorseddirs`, and `-XXuserPathsFirst` may not be used.

Single-module mode is used to compile code organized in a traditional
package-hierarchical directory tree.  It is the natural replacement for
simple uses of legacy mode of the form

    $ javac -d classes -classpath classes -sourcepath src Foo.java

If a module descriptor in the form of a `module-info.java` or
`module-info.class` file is specified on the command line, or is found on
the source path or the class path, then source files will be compiled as
members of the module named by that descriptor and that module will be
the sole root module.  Otherwise if the `--module <module>` option is
present then source files will be compiled as members of `<module>`,
which will be the root module.  Otherwise source files will be compiled
as members of the unnamed module, and the root modules will be computed
[as described above](#root-modules).

It is possible to put arbitrary classes and JAR files on the class path
in this mode, but that is not recommended since it amounts to treating
those classes and JAR files as part of the module being compiled.

  - _Multi-module mode_ is enabled when the compilation environment is 9
    or later and the `--module-source-path` option is used.  The existing
    `-d` option to name the output directory must also be used; the other
    modular options described above may be used; the existing options
    `-bootclasspath`, `-Xbootclasspath`, `-extdirs`, `-endorseddirs`, and
    `-XXuserPathsFirst` may not be used.

Multi-module mode is used to compile one or more modules, whose source
code is laid out in exploded-module directories on the module source
path.  In this mode the module membership of a type is determined by the
position of its source file in the module source path, so each source
file specified on the command line must exist within an element of that
path.  The set of root modules is the set of modules for which at least
one source file is specified.

In contrast to the other modes, in this mode an output directory must be
specified via the `-d` option.  The output directory will be structured
as an element of a module path, _i.e._, it will contain exploded-module
directories which themselves contain class and resource files.  If the
compiler finds a module on the module source path but cannot find the
source file for some type in that module then it will search the output
directory for the corresponding class file.

In large systems the source code for a particular module may be spread
across several different directories.  [In the JDK itself][jep201],
_e.g._, the source files for a module may be found in any one of the
directories `src/<module>/share/classes`, `src/<module>/<os>/classes`, or
`build/gensrc/<module>`, where `<os>` is the name of the target operating
system.  To express this in a module source path while preserving module
identities we allow each element of such a path to use braces (`{` and
`}`) to enclose commas-separated lists of alternatives and a single
asterisk (`*`) to stand for the module name.  The module source path for
the JDK can then be written as

    {src/*/{share,<os>}/classes,build/gensrc/*}

In both of the modular modes the compiler will, by default, generate
various warnings related to the module system; these may be disabled via
the option `-Xlint:-module`.  More precise control of these warnings is
available via the `exports`, `opens`, `requires-automatic`, and
`requires-transitive-automatic` keys for the `-Xlint` option.

The new option `--module-version <version>` may be used to specify the
version strings of the modules being compiled.


### Class-file attributes

A JDK-specific class-file attribute, `ModuleTarget`, optionally records
the target operating system and architecture of the module descriptor
that contains it.  Its format is:

    ModuleTarget_attribute {
        u2 attribute_name_index;
        u4 attribute_length;
        u2 os_arch_index; // index to a CONSTANT_utf8_info structure
    }

The UTF-8 string in the constant pool at `os_arch_index` has the format
`<os>-<arch>`, where `<os>` is typically one of `linux`, `macos`,
`solaris`, or `windows`, and `<arch>` is typically one of `x86`, `amd64`,
`sparcv9`, `arm`, or `aarch64`.


### Packaging: Modular JAR files

The `jar` tool can be used without change to create
[modular JAR files][sotms-ma], since a modular JAR file is just a JAR
file with a `module-info.class` file in its root directory.

The `jar` tool implements the following new options to allow the
insertion of additional information into module descriptors as modules
are packaged:

  - `--main-class=<class-name>`, or `-e <class-name>` for short, causes
    `<class-name>` to be recorded in the `module-info.class` file as the
    class containing the module's `public static void main` entry point.
    (This is not a new option; it already records the main class in the
    JAR file's manifest.)

  - `--module-version=<version>` causes `<version>` to be recorded in the
    `module-info.class` file as the module's version string.

  - `--hash-modules=<pattern>` causes hashes of the content of the
    specific modules that depend upon this module, in a particular set of
    observable modules, to be recorded in the `module-info.class` file
    for later use in the validation of dependencies.  Hashes are only
    recorded for modules whose names match the regular expression
    `<pattern>`.  If this option is used then the `---module-path`
    option, or `-p` for short, must also be used to specify the set of
    observable modules for the purpose of computing the modules that
    depend upon this module.

  - `--describe-module`, or `-d` for short, displays the module
    descriptor, if any, of the specified JAR file.

The `jar` tool's `--help` option can be used to show a complete summary
of its command-line options.

Two new JDK-specific JAR-file manifest attributes are defined to
correspond to the `--add-exports` and `--add-opens` command-line options:

  - `Add-Exports: <module>/<package>( <module>/<package>)*`
  - `Add-Opens: <module>/<package>( <module>/<package>)*`

The value of each attribute is a space-separated list of slash-separated
module-name/package-name pairs.  A `<module>/<package>` pair in the value
of an `Add-Exports` attribute has the same meaning as the command-line
option `--add-exports <module>/<package>=ALL-UNNAMED`.  A
`<module>/<package>` pair in the value of an `Add-Opens` attribute has
the same meaning as the command-line option `--add-opens
<module>/<package>=ALL-UNNAMED`.

Each attribute can occur at most once, in the main section of a
`MANIFEST.MF` file.  A particular pair can be listed more than once.  If
a specified module was not resolved, or if a specified package does not
exist, then the corresponding pair is ignored.  These attributes are
interpreted only in the main executable JAR file of an application, i.e.,
in the JAR file specified to the `-jar` option of the Java run-time
launcher; they are ignored in all other JAR files.

[sotms-ma]: http://openjdk.java.net/projects/jigsaw/spec/sotms/#module-artifacts


### Packaging: JMOD files

The new JMOD format goes beyond JAR files to include native code,
configuration files, and other kinds of data that do not fit naturally,
if at all, into JAR files.  JMOD files are used to package the modules of
the JDK itself; they can also be used by developers to package their own
modules, if desired.

JMOD files can be used at compile time and link time, but not at run
time.  To support them at run time would require, in general, that we be
prepared to extract and link native-code libraries on-the-fly.  This is
feasible on most platforms, though it can be very tricky, and we have not
seen many use cases that require this capability, so for simplicity we
have chosen to limit the utility of JMOD files in this release.

A new command-line tool, `jmod`, can be used to create, manipulate, and
examine JMOD files.  Its general syntax is:

    $ jmod (create|extract|list|describe|hash) <options> <jmod-file>

For the `create` subcommand, `<options>` can include the `--main-class`,
`--module-version`, `--hash-modules`, and `---module-path` options
described above for the `jar` tool, and also:

  - `--class-path <path>` specifies a class path whose content will be
    copied into the resulting JMOD file.

  - `--cmds <path>` specifies one or more directories containing native
    commands to be copied.

  - `--config <path>` specifies one or more directories containing
    configuration files to be copied.

  - `--exclude <pattern-list>` specifies files to be excluded, where
    `<pattern-list>` is a comma-separated list of patterns of the form
    `<glob-pattern>`, `glob:<glob-pattern>`, or `regex:<regex-pattern>`.

  - `--header-files <path>` specifies one or more directories containing
    C and C++ header files to be copied.

  - `--legal-notices <path>` specifies one or more directories containing
    legal notices to be copied.

  - `--libs <path>` specifies one or more directories containing native
    libraries to be copied.

  - `--man-pages <path>` specifies one or more directories containing
    manual pages to be copied.

  - `--target-platform <os>-<arch>` specifies the target operating system
    and architecture, to be recorded in the `ModuleTarget` attribute of
    the `module-info.class` file.

The `extract` subcommand accepts a single option, `--dir`, to indicate
the directory into which the content of the specified JMOD file should be
written.  The directory will be created if it does not exist.  If this
option is not present then the content will be extracted into the current
directory.

The `list` subcommand lists the content of the specified JMOD file; the
`describe` subcommand displays the module descriptor of the specified
JMOD file, in the same format as the `--describe-module` options of the
`jar` and `java` commands.  These subcommands accept no options.

The `hash` subcommand can be used to hash an existing set of JMOD files.
It requires both the `--module-path` and `--hash-modules` options.

The `jmod` tool's `--help` option can be used to show a complete summary
of its command-line options.


### Link time

The details of the command-line linking tool, `jlink`, are described in
[JEP 282][jep282].  At a high level its general syntax is:

    $ jlink <options> ---module-path <modulepath> --output <path>

where the `---module-path` option specifies the set of observable modules
to be considered by the linker and the `--output` option specifies the
path of the directory that will contain the resulting run-time image.
The other `<options>` can include the `---limit-modules` and
`---add-modules` options, described above, as well as additional
linker-specific options.

The `jlink` tool's `--help` option can be used to show a complete summary
of its command-line options.


### Run time

The HotSpot virtual machine implements the options described above, as
applicable to run time: `--upgrade-module-path`, `--module-path`,
`--add-modules`, `--limit-modules`, `--add-reads`, `--add-exports`,
`--add-opens`, and `--patch-module`.  These options can be passed to the
command-line launcher, `java`, and also to the
[JNI invocation API][jinv].

An additional option specific to this phase and supported by the launcher
is:

  - `--module <module>`, or `-m <module>` for short, specifies the main
    module of a modular application.  This will be the default root
    module for the purpose of constructing the application's initial
    module graph.  If the main module's descriptor does not indicate a
    main class then the syntax `<module>/<class>` can be used, where
    `<class>` names the class that contains the application's `public
    static void main` entry point.

Additional diagnostic options supported by the launcher include:

  - `--list-modules` displays the names and version strings of the
     observable modules and then exits, in the same manner as `java
     --version`.

  - `--describe-module <module>`, or `-d <module>` for short, displays
    the module descriptor of the specified module, in the same format as
    the `jar -d` option and the `jmod describe` subcommand, and then
    exits.

  - `--validate-modules` validates all the observable modules, checking
    for conflicts and other potential errors, and then exits.

  - `--dry-run` initializes the virtual machine and loads the main class
    but does not invoke the main method; this is useful for validating
    the configuration of the module system.

  - `--show-module-resolution` causes the module system to describe its
    activities as it constructs the initial module graph.

  - `-Dsun.reflect.debugModuleAccessChecks` causes a thread dump to be
    shown whenever an access check in the `java.lang.reflect` API fails
    with an `IllegalAccessException` or an `InaccessibleObjectException`.
    This is useful for debugging when the underlying reason for a failure
    is hidden because the exception is caught and not re-thrown.

  - `-Xlog:module+[load|unload][=[debug|trace]]` causes the VM to log
    debug or trace messages as modules are defined and changed in the
    run-time module graph.  These options generate voluminous output
    during startup.

  - `-verbose:module` is a shorthand for `-Xlog:module+load
    -Xlog:module+unload`.

  - `-Xlog:init=debug` causes a stack trace to be displayed if the
    initialization of the module system fails.

  - `--version`, `--show-version`, `--help`, and `--help-extra` display
    the same information and work in the same way as the existing
    `-version`, `-show-version`, `-help`, and `-Xhelp` options,
    respectively, except that they write the help text to the standard
    output stream rather than the standard error stream.

The stack traces generated for exceptions at run time have been extended
to include, when present, the names and version strings of relevant
modules.  The detail strings of exceptions such as `ClassCastException`,
`IllegalAccessException`, and `IllegalAccessError` have also been updated
to include module information.

The existing `-jar` option has been enhanced so that if the manifest file
of the JAR file being launched contains a `Launcher-Agent-Class`
attribute then the JAR file is launched as both an application and as an
agent for that application. This allows `java -jar foo.jar` to be used in
place of the more verbose `java -javaagent:foo.jar -jar foo.jar`.

[jinv]: http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html


### Relaxed strong encapsulation

In this release the strong encapsulation of some of the JDK's packages is
relaxed by default,
[as permitted by the Java SE&nbsp;9 Platform Specification][se9-relax].
This relaxation is controlled at run time by a new launcher option,
`--illegal-access`, which works as follows:

  - `--illegal-access=permit` opens each package in each module in the
    run-time image to code in all unnamed modules, _i.e._, to code on the
    class path, if that package existed in JDK 8.  This enables both
    static access, _i.e._, by compiled bytecode, and deep reflective
    access, via the platform's various reflection APIs.

    The first reflective-access operation to any such package causes a
    warning to be issued, but no warnings are issued after that point.
    This single warning describes how to enable further warnings.  This
    warning cannot be suppressed.

    This mode is the default in JDK 9.  It will be phased out in a future
    release and, eventually, removed.

  - `--illegal-access=warn` is identical to `permit` except that a
    warning message is issued for each illegal reflective-access
    operation.

  - `--illegal-access=debug` is identical to `warn` except both a warning
    message and a stack trace are issued for each illegal
    reflective-access operation.

  - `--illegal-access=deny` disables all illegal-access operations except
    for those enabled by other command-line options, e.g., `--add-opens`.

    This mode will become the default in a future release.

When `deny` becomes the default illegal-access mode then `permit` will
likely remain supported for at least one release, so that developers can
continue to migrate their code.  The `permit`, `warn`, and `debug` modes
will, over time, be removed, as will the `--illegal-access` option
itself.  (For launch-script compatibility the unsupported modes will most
likely just be ignored, after issuing a warning to that effect.)

The default mode, `--illegal-access=permit`, is intended to make you
aware when you have code on the class path that reflectively accesses
some JDK-internal API at least once.  To prepare for the future you can
use the `warn` or `debug` modes to learn about all such accesses.  For
each library or framework on the class path that requires illegal access
you have two options:

  - If the component's maintainers have already released a new, fixed
    version that no longer uses JDK-internal APIs then you can consider
    upgrading to that version.

  - If the component still needs to be fixed then we encourage you to
    contact its maintainers and ask them to replace their use of
    JDK-internal APIs with proper exported APIs, if available.

If you must continue to use a component that requires illegal access then
you can eliminate the warning messages by using one or more `--add-opens`
options to open just those internal packages to which access is required.

To verify that your application is ready for the future, run it with
`--illegal-access=deny` along with any necessary `--add-opens` options.
Any remaining illegal-access errors will most likely be due to static
references from compiled code to JDK-internal APIs.  You can identify
those by running the `jdeps` tool with the `--jdk-internals` option.
(The run-time system does not issue warnings for illegal static-access
operations because that would require deep VM changes and degrade
performance.)

The warning message issued when an illegal reflective-access operation is
detected has the following form:

    WARNING: Illegal reflective access by $PERPETRATOR to $VICTIM

where:

  - $PERPETRATOR is the fully-qualified name of the type containing
    the code that invoked the reflective operation in question plus
    the code source (i.e., JAR-file path), if available, and

  - $VICTIM is a string that describes the member being accessed,
    including the fully-qualified name of the enclosing type

In the default mode, `--illegal-access=permit`, at most one of these
warning messages will be issued, accompanied by additional instructive
text.  Here is an example, from running Jython:

    $ java -jar jython-standalone-2.7.0.jar
    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by jnr.posix.JavaLibCHelper (file:/tmp/jython-standalone-2.7.0.jar) to method sun.nio.ch.SelChImpl.getFD()
    WARNING: Please consider reporting this to the maintainers of jnr.posix.JavaLibCHelper
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release
    Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11) 
    [OpenJDK 64-Bit Server VM (Oracle Corporation)] on java9
    Type "help", "copyright", "credits" or "license" for more information.
    >>> ^D

The run-time system makes a best-effort attempt to suppress duplicate
warnings for the same $PERPETRATOR and $VICTIM.

[se9-relax]: http://cr.openjdk.java.net/~iris/se/9/java-se-9-fr-spec-01/#Relaxing-strong-encapsulation


### An extended example

Suppose we have an application module, `com.foo.bar`, which depends upon
a library module, `com.foo.baz`.  If we have the source code for both
modules in the module-path directory `src`:

    src/com.foo.bar/module-info.java
    src/com.foo.bar/com/foo/bar/Main.java
    src/com.foo.baz/module-info.java
    src/com.foo.baz/com/foo/baz/BazGenerator.java

then we can compile them, together:

    $ javac --module-source-path src -d mods $(find src -name '*.java')

The output directory, `mods`, is a module-path directory containing
exploded, compiled definitions of the two modules:

    mods/com.foo.bar/module-info.class
    mods/com.foo.bar/com/foo/bar/Main.class
    mods/com.foo.baz/module-info.class
    mods/com.foo.baz/com/foo/baz/BazGenerator.class

Assuming that the `com.foo.bar.Main` class contains the application's
entry point, we can run these modules as-is:

    $ java -p mods -m com.foo.bar/com.foo.bar.Main

Alternatively, we can package them up into modular JAR files:

    $ jar --create -f mlib/com.foo.bar-1.0.jar \
          --main-class com.foo.bar.Main --module-version 1.0 \
          -C mods/com.foo.bar .
    $ jar --create -f mlib/com.foo.baz-1.0.jar \
          --module-version 1.0 -C mods/com.foo.baz .

The `mlib` directory is a module-path directory containing the packaged,
compiled definitions of the two modules:

    $ ls -l mlib
    -rw-r--r-- 1501 Sep  6 12:23 com.foo.bar-1.0.jar
    -rw-r--r-- 1376 Sep  6 12:23 com.foo.baz-1.0.jar

We can now run the packaged modules directly:

    $ java -p mlib -m com.foo.bar


### `jtreg` enhancements

The [jtreg test harness][jtreg] supports a new declarative tag,
`@modules`, to express a test's dependences upon the modules in the
system being tested.  It takes a series of space-separated arguments,
each of which can be of the form

  - `<module>`, where `<module>` is a module name, to indicate that the
    specified module must be present;

  - `<module>/<package>`, to indicate that the specified module must be
    present and the specified package must be exported to the test's
    module; or

  - `<module>/<package>:<flag>`, to indicate that the specified module
    must be present and, if the flag is `open` then the specified package
    must be opened to the test's module, or else if the flag is `+open`
    then the specified package must be both exported and opened to the
    test's module.

A default set of `@modules` arguments, which will be used for all tests
in a directory hierarchy that do not include such a tag, can be specified
as the value of the `modules` property in a `TEST.ROOT` file or in any
`TEST.properties` file.

The existing `@compile` tag accepts a new option, `/module=<module>`.
This has the effect of invoking `javac` with the `--module <module>`
option, defined above, to compile the specified classes as members of the
indicated module.

[jtreg]: http://openjdk.java.net/jtreg/
[jtreg-tags]: http://openjdk.java.net/jtreg/tag-spec.html


### Class loaders

The Java SE Platform API historically specified two class loaders: The
_bootstrap class loader_, which loads classes from the bootstrap class
path, and the [_system class loader_][syscl], which is the default
delegation parent for new class loaders and, typically, the class loader
used to load and start the application.  The specification does not
mandate the concrete types of either of these class loaders, nor their
precise delegation relationship.

The JDK has, since the 1.2 release, implemented a three-level hierarchy
of class loaders, where each loader delegates to the next:

  - The application class loader, an instance of
    `java.net.URLClassLoader`, loads classes from the class path and is
    installed as the system class loader unless an alternate system
    loader is specified via the system property
    `java.system.class.loader`.

  - The extension class loader, also an instance of `URLClassLoader`,
    loads classes available via the [extension mechanism][ext] and, also,
    some resources and service providers built-in to the JDK.  (This
    loader is not mentioned explicitly in the Java SE Platform API
    Specification.)

  - The bootstrap class loader, which is implemented solely within the
    virtual machine and is represented by `null` in the `ClassLoader`
    API, loads classes from the bootstrap class path.

JDK 9 retains this three-level hierarchy, in order to preserve
compatibility, while making the following changes to implement the module
system:

  - The application class loader is no longer an instance of
    `URLClassLoader` but, rather, of an internal class.  It is the
    default loader for named modules that are neither Java SE nor JDK
    modules.

  - The extension class loader is no longer an instance of
    `URLClassLoader` but, rather, of an internal class.  It no longer
    loads classes via the extension mechanism, which was removed by
    [JEP 220][jep220].  It does, however, define selected Java SE and JDK
    modules, about which more below.  In its new role this loader is
    known as the _platform class loader_, it is available via the new
    `ClassLoader::getPlatformClassLoader`
    [method][api-getPlatformLoader], and it will be required by the
    Java&nbsp;SE Platform API Specification.

  - The bootstrap class loader is implemented in both library code and
    within the virtual machine, but for compatibility it is still
    represented by `null` in the `ClassLoader` API.  It defines the core
    Java&nbsp;SE and JDK modules.

The platform class loader is retained not only for compatibility but,
also, to improve security.  Types loaded by the bootstrap class loader
are implicitly granted all security permissions (`AllPermission`), but
many of these types do not actually require all permissions.  We have
_de-privileged_ modules that do not require all permissions by defining
them to the platform loader rather than the bootstrap class loader, and
by granting them the permissions they actually need in the default
security policy file.  The Java SE and JDK modules defined to the
platform class loader are:

    java.activation*            jdk.accessibility
    java.compiler*              jdk.charsets
    java.corba*                 jdk.crypto.cryptoki
    java.scripting              jdk.crypto.ec
    java.se                     jdk.dynalink
    java.se.ee                  jdk.incubator.httpclient
    java.security.jgss          jdk.internal.vm.compiler*
    java.smartcardio            jdk.jsobject
    java.sql                    jdk.localedata
    java.sql.rowset             jdk.naming.dns
    java.transaction*           jdk.scripting.nashorn
    java.xml.bind*              jdk.security.auth
    java.xml.crypto             jdk.security.jgss
    java.xml.ws*                jdk.xml.dom
    java.xml.ws.annotation*     jdk.zipfs

(An asterisk, `'*'`, in these lists indicates an upgradeable module.)

JDK modules that provide tools or export tool APIs are defined to the
application class loader:

    jdk.aot                     jdk.jdeps
    jdk.attach                  jdk.jdi
    jdk.compiler                jdk.jdwp.agent
    jdk.editpad                 jdk.jlink
    jdk.hotspot.agent           jdk.jshell
    jdk.internal.ed             jdk.jstatd
    jdk.internal.jvmstat        jdk.pack
    jdk.internal.le             jdk.policytool
    jdk.internal.opt            jdk.rmic
    jdk.jartool                 jdk.scripting.nashorn.shell
    jdk.javadoc                 jdk.xml.bind*
    jdk.jcmd                    jdk.xml.ws*
    jdk.jconsole

All other Java SE and JDK modules are defined to the bootstrap class
loader:

    java.base                   java.security.sasl
    java.datatransfer           java.xml
    java.desktop                jdk.httpserver
    java.instrument             jdk.internal.vm.ci
    java.logging                jdk.management
    java.management             jdk.management.agent
    java.management.rmi         jdk.naming.rmi
    java.naming                 jdk.net
    java.prefs                  jdk.sctp
    java.rmi                    jdk.unsupported

The three built-in class loaders work together to load classes as
follows:

  - The application class loader first searches the named modules defined
    to all of the built-in loaders.  If a suitable module is defined to
    one of these loaders then that loader will load the class.  If a
    class is not found in a named module defined to one of these loaders
    then the application class loader delegates to its parent.  If a
    class is not found by its parent then the application class loader
    searches the class path.  Classes found on the class path are loaded
    as members of this loader's unnamed module.

  - The platform class loader searches the named modules defined to all
    of the built-in loaders.  If a suitable module is defined to one of
    these loaders then that loader will load the class.  (The platform
    class loader can, consequently, now delegate to the application class
    loader, which can be useful when a module on the upgrade module path
    depends upon a module on the application module path.)  If a class is
    not found in a named module defined to one of these loaders then the
    platform class loader delegates to its parent.

  - The bootstrap class loader searches the named modules defined to
    itself.  If a class is not found in a named module defined to the
    bootstrap loader then the bootstrap class loader searches the files
    and directories added to the bootstrap class path via the
    `-Xbootclasspath/a` option.  Classes found on the bootstrap class
    path are loaded as members of this loader's unnamed module.

The application and platform class loaders delegate to their respective
parent loaders in order to ensure that the bootstrap class path is still
searched when a class is not found in a module defined to one of the
built-in loaders.

[syscl]: http://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html#getSystemClassLoader--
[ext]: http://docs.oracle.com/javase/8/docs/technotes/guides/extensions/index.html
[api-getPlatformLoader]: http://download.java.net/java/jdk9/docs/api/java/lang/ClassLoader.html#getPlatformClassLoader--


### Removed: Bootstrap class-path options

In earlier releases the `-Xbootclasspath` option allows the default
bootstrap class path to be overridden, and the `-Xbootclasspath/p` option
allows a sequence of files and directories to be prepended to the default
path.  The computed value of this path is reported via the JDK-specific
system property `sun.boot.class.path`.

With the module system in place the bootstrap class path is empty by
default, since bootstrap classes are loaded from their respective
modules.  The `javac` compiler only supports the `-Xbootclasspath` option
in legacy mode, the `java` launcher no longer supports either of these
options, and the system property `sun.boot.class.path` has been removed.

The compiler's `--system` option can be used to specify an alternate
source of system modules, as described above, and its `-release` option
can be used to specify an alternate platform version, as described in
[JEP 247 (Compile for Older Platform Versions)][jep247].  At run time the
`--patch-module` option, mentioned above, can be used to inject content
into modules in the initial module graph.

A related option, `-Xbootclasspath/a`, allows files and directories to be
appended to the default bootstrap class path.  This option, and the
related API in the `java.lang.instrument` package, is sometimes used by
instrumentation agents, so for compatibility it is still supported at run
time.  Its value, if specified, is reported via the JDK-specific system
property `jdk.boot.class.path.append`.  This option can be passed to the
command-line launcher, `java`, and also to the JNI invocation API.

[jep247]: http://openjdk.java.net/jeps/247


Testing
-------

Many existing tests were affected by the introduction of the module
system.  In JDK&nbsp;9 the `@modules` tag, described above, was added to
the unit and regression tests as needed, and tests that used the
`-Xbootclasspath/p` option or assumed that the system class loader is a
`URLClassLoader` were updated.

There is, of course, an extensive set of unit tests for the module system
itself.  In the JDK&nbsp;9 source forest the run-time tests are in the
[test/jdk/modules][test-jdk] directory of the `jdk` repository and the
[runtime/modules][test-hotspot] directory of the `hotspot` repository;
the compile-time tests are in the [tools/javac/modules][test-langtools]
directory of the `langtools` repository.

[test-jdk]: http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/test/jdk/modules
[test-hotspot]: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/tip/test/runtime/modules
[test-langtools]: http://hg.openjdk.java.net/jdk9/jdk9/langtools/file/tip/test/tools/javac/modules

Early-access builds containing the changes described here were available
throughout the development of the module system.  Members of the Java
community were strongly encouraged to test their tools, libraries, and
applications against these builds to help identify compatibility issues.


Risks and Assumptions
---------------------

The primary risks of this proposal are ones of compatibility due to
changes to existing language constructs, APIs, and tools.

Changes due primarily to the introduction of the
[Java Platform Module System (JSR 376)][jpms] include:

  - Applying the `public` modifier to an API element no longer guarantees
    that the element will be everywhere accessible.  Accessibility now
    depends also upon whether the package containing that element is
    exported or opened by its defining module, and whether that module is
    readable by the module containing the code that is attempting to
    access it.  For example, code of the following form might not work
    correctly:

        Class<?> c = Class.forName(...);
        if (Modifier.isPublic(c.getModifiers()) {
            // Assume that c is accessible
        }

  - If a package is defined in both a named module and on the class path
    then the package on the class path will be ignored.  The class path
    can, therefore, no longer be used to augment packages that are built
    into the environment.  The `javax.transaction` package, _e.g._, is
    defined by the `java.transaction` module, so the class path will not
    be searched for types in that package.  This restriction is important
    to avoid splitting packages across class loaders and across modules.
    At compile time and run time the upgrade module path can be used to
    upgrade modules that are built-in into the environment.  The
    `--patch-module` option can be used for other ad-hoc patching.

  - The `ClassLoader::getResource*` methods can no longer be used to
    locate JDK-internal resources other than class files.  Module-private
    non-class resources can be read via the `Class::getResource*`
    methods, the `Module::getResourceAsStream` method or via the `jrt:`
    URL scheme and filesystem defined in [JEP 220][jep220].

  - The `java.lang.reflect.AccessibleObject::setAccessible`
    [method][api-setAccessible] cannot be used to gain access to public
    members of packages that are not exported or opened by their defining
    modules, or to non-public members of packages that are not opened by
    their defining modules; in either case, an
    `InaccessibleObjectException` will be thrown.  If a framework
    library, such as a serializer, needs access to such members at run
    time then the relevant packages must be opened to the framework
    module by declaring the containing module to be open, by declaring
    that package to be open, or by opening that package via the
    `--add-opens` command-line option.

  - JVM TI agents can no longer instrument Java code that runs early in
    the startup of the run-time environment.  The `ClassFileLoadHook`
    event, in particular, is no longer sent during the primordial phase.
    The `VMStart` event, which signals the beginning of the start phase,
    is only posted after the the VM is initialized to the point where it
    can load classes in modules other than `java.base`.  Two new
    capabilities, `can_generate_early_class_hook_events` and
    `can_generate_early_vmstart`, can be added by agents that are
    carefully written to handle events early in VM initialization.  More
    details can be found in the updated description of the [class file load hook event](http://download.java.net/java/jdk9/docs/platform/jvmti/jvmti.html#ClassFileLoadHook)
    and the [start event](http://download.java.net/java/jigsaw/docs/platform/jvmti/jvmti.html#VMStart).

  - The `==` syntax in security policy files has been revised to augment
    the permissions granted to standard and JDK modules rather than
    override them.  Applications that override other aspects of the JDK's
    default policy file therefore do not need to copy the default
    permissions granted to the standard and JDK modules.

<a id="EE-modules">Modules that define Java EE APIs,</a> or APIs
primarily of interest to Java EE applications, have been deprecated and
will be removed in a future release.  They are not resolved by default
for code on the class path:

  - The default set of root modules for the unnamed module is based, in
    JDK&nbsp;9, upon the `java.se` module rather than the `java.se.ee`
    module.  Thus, by default, code in the unnamed module will not have
    access to APIs in the following modules:

        java.activation
        java.corba
        java.transaction
        java.xml.bind
        java.xml.ws
        java.xml.ws.annotation

    This is an intentional, if painful, choice, driven by two goals:

      - To avoid unnecessary conflicts with popular libraries that define
        types in some of the same packages.  The widely-used
        `jsr305.jar`, _e.g._, defines annotation types in the
        `javax.annotation` package, which is also defined by the
        `java.xml.ws.annotation` module.

      - To make it easier for existing application servers to migrate to
        JDK&nbsp;9.  Application servers often override the content of
        one or more of these modules, and in the near term they are most
        likely to do so by continuing to place the necessary non-modular
        JAR files on the class path.  If these modules were resolved by
        default then the maintainers of application servers would have to
        take awkward actions to exclude them in order to override them.

    These modules are still part of JDK&nbsp;9.  Code on the class path
    can be granted access to one or more of these modules, as needed, via
    the `--add-modules` option.

The run-time behavior of some Java SE APIs has changed, though in ways
that continue to honor their existing specifications:

  - The application and platform class loaders are no longer instances of
    the `java.net.URLClassLoader` class, as noted above.  Existing code
    that invokes `ClassLoader::getSystemClassLoader` and blindly casts
    the result to `URLClassLoader`, or does the same thing with the
    parent of that class loader, might not work correctly.

  - Some Java SE types have been de-privileged and are now loaded by the
    platform class loader rather than the bootstrap class loader, as
    noted above.  Existing custom class loaders that delegate directly to
    the bootstrap class loader might not work correctly; they should be
    updated to delegate to the platform class loader, which is easily
    available via the new `ClassLoader::getPlatformClassLoader`
    [method][api-getPlatformLoader].

  - Instances of `java.lang.Package` created by the built-in class
    loaders for packages in named modules do not have specification or
    implementation versions.  In previous releases this information was
    read from the manifest of `rt.jar`.  Existing code that expects the
    `Package::getSpecification*` or `Package::getImplementation*` methods
    always to return non-null values might not work correctly.

There are several source-incompatible Java SE API changes:

  - The `java.lang` package includes two new top-level classes, `Module`
    and `ModuleLayer`.  The `java.lang` package is implicitly imported on
    demand (_i.e._, `import java.lang.*`).  If code in an existing source
    file imports some other package on demand, and that package declares
    a `Module` or `ModuleLayer` type, and the existing code refers to
    that type, then the file will not compile without change.

  - The `java.lang.instrument.Instrumentation` interface declares two new
    abstract methods, `redefineModule` and `isModifiableModule`.  This
    interface is not intended to be implemented outside of the
    `java.instrument` module.  If there are external implementations then
    they will not compile on JDK&nbsp;9 without change.

  - The five-parameter `transform` method declared in the
    `java.lang.instrument.ClassFileTransformer` interface is now a
    default method.  The interface now also declares a new `transform`
    method that makes the relevant `java.lang.reflect.Module` object
    available to the transformer when instrumenting classes at load time.
    Existing compiled code will continue to run, but existing source code
    that uses the existing five-parameter transform method as a
    functional interface will no longer compile.

Finally, changes due to revisions to JDK-specific APIs and tools include:

  - Most of the JDK's internal APIs are inaccessible by default at
    compile time, as described in [JEP 260][jep260].  Existing code that
    compiled against these APIs with warnings in previous releases will
    no longer compile.  A workaround is to break encapsulation via the
    `--add-exports` option, defined above.

  - Selected critical internal APIs in the `sun.misc` and `sun.reflect`
    packages have been moved to the `jdk.unsupported` module, as
    described in JEP&nbsp;260.  Non-critical internal APIs in these
    packages, such as `sun.misc.BASE64{De,En}coder`, have been either
    moved or removed.

  - If a security manager is present then the run-time permission
    `accessSystemModules` is required in order to access JDK-internal
    resources via the `ClassLoader::getResource*` or
    `Class::getResource*` methods; in previous releases, permission to
    read the file `${java.home}/lib/rt.jar` was required.

  - The `-Xbootclasspath` and `-Xbootclasspath/p` options have been
    removed, as noted above.  At compile time, the new `--release` option
    can be used to specify an alternate platform version (see
    [JEP 247][jep247]).  At run time, the new `--patch-module` option,
    described above, can be used to inject content into system modules.

  - The JDK-specific system property `sun.boot.class.path` has been
    removed, since the bootstrap class path is empty by default.
    Existing code that uses this property might not work correctly.

  - The JDK-specific annotation `@jdk.Exported`, introduced by
    [JEP 179][jep179], has been removed since the information it conveys
    is now recorded in the `exports` declarations of module descriptors.
    We have seen no evidence of this annotation being used by tools
    outside of the JDK.

  - The `META-INF/services` resource files previously found in `rt.jar`
    and other internal artifacts are not present in the corresponding
    system modules, since service providers and dependences are now
    declared in module descriptors.  Existing code that scans for such
    files might not work correctly.

  - The JDK-specific system property `file.encoding` can be set on the
    command line via the `-D` option, as before, but it must specify a
    charset defined in the base module.  If any other charset is
    specified then the run-time system will fail to start.  Existing
    launch scripts that specify such charsets might not work correctly.

  - The `com.sun.tools.attach` API can no longer be used, by default, to
    attach an agent to the current process or an ancestor of the current
    process.  Such attachment operations can be enabled by setting the
    system property `jdk.attach.allowAttachSelf` on the command line.

  - The dynamic loading of JVM TI agents will be disabled by default in a
    future release.  To prepare for that change we recommend that
    applications that allow dynamic agents start using the option
    `-XX:+EnableDynamicAgentLoading` to enable that loading explicitly.
    The option `-XX:-EnableDynamicAgentLoading` disables dynamic agent
    loading.

[jep179]: http://openjdk.java.net/jeps/179


Dependences
-----------

[JEP 200 (The Modular JDK)][jep200] originally defined the modules
present in the JDK in an XML document, as an interim measure.  This JEP
moved those definitions to proper module descriptors, _i.e._,
`module-info.java` and `module-info.class` files, and the `modules.xml`
file in the root source-code repository was removed.

The initial implementation of [JEP 220 (Modular Run-Time Images)][jep220]
in JDK&nbsp;9 used a custom build-time tool to construct JRE and JDK
images.  This JEP replaced that tool with the `jlink` tool.

Modular JAR files can also be Multi-Release JAR files, per
[JEP 238][jep238].

[jep238]: http://openjdk.java.net/jeps/238

Comments
FC Extension Request The foundations of the module system were integrated this past March, and appear to be in pretty good shape. We expect further revisions as the JSR 376 EG works through its issue list [1], and in response to further feedback from the wider developer community. Late changes in this area are not without risk, and at present that risk is difficult to estimate. We expect few if any changes, however, in the VM or the client libraries; most changes would be in the core libraries and the compiler (javac), for which test execution is fully automated and run on all supported platforms continuously. Estimated completion: 2016/9/1
22-06-2016

Updated with the revised algorithm for computing the default set of root modules for class-path applications.
02-04-2016

Linked to JDK-8142968, as we'll use that JIRA issue for the push to JDK 9.
06-01-2016

Updated to evolve -Xoverride into -Xpatch, and bring back -XaddReads, thereby closing several open design issues.
28-09-2015