Java 9 Modules: Difference between revisions
(57 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=External= | |||
* https://www.baeldung.com/java-9-modularity | |||
* https://www.oracle.com/corporate/features/understanding-java-9-modules.html | |||
* https://www.infoq.com/presentations/java-9-modules | |||
=Internal= | =Internal= | ||
* [[Java#Java9|Java]] | |||
=Concepts= | |||
==Module== | |||
A '''module''' is a group of closely related Java packages and resources, shipped together with a module descriptor file [[#module-info.java|module-info.java]]. A module can be thought of as a package of Java packages. Modules are exposed to the JVM on the [[#Module_Path|modulepath]]. Modules can be distributed as JARs or as "exploded" compiled projects. When distributed as JARs, there could be just one module per JAR file - each module should be bundled as a separate JAR. | |||
===Module Types=== | |||
====System Module==== | |||
A system module is a named module available with the JDK. They can be listed with <code>java --list-modules</code> See [[#List_Modules|List Modules]] below. The system modules are split in at least two major groups: <code>java</code>, which contain the implementation classes for the core SE Language Specification, and <code>jdk</code>, which contains code needed by the JDK. | |||
====Application Module==== | |||
Custom modules we usually build. They are named and defined in [[#module-info.java|module-info.java]] descriptor included in the artifact JAR. | |||
====Automatic Module==== | |||
For JARs created before Java 9, code will get a module name derived from the JAR file name if an existing JAR that was not built as a module is added to [[#Modulepath|modulepath]]. Automatic modules have full read access to every other module loaded from the modulepath. | |||
====Unnamed Module==== | |||
The "unnamed" module contains code compiled without a [[#module-info.java|module-info.java]] descriptor and exposed to the JVM on [[#Classpath|classpath]]. This is a catch-all module introduced to maintain compatibility with pre-Java 9 artifacts. The "unnamed" module code can see by default all other code in the "unnamed" and <code>java.base</code> modules, and modules in the <code>java.se</code> [[#Root_Module|root module]]. That means if no <code>module-info.java</code> is present in the project, everything should still work as in Java 8. For this case, dependencies should be continued to be put on the [[#Classpath|classpath]], not on [[#Modulepath|modulepath]]. | |||
===Root Module=== | |||
===ALL-UNNAMED=== | |||
==<span id='module-info.java'></span>Module Descriptor <code>module-info.java</code>== | |||
<code>module-info.java</code> is file that represents a module descriptor. If the code is compiled with a <code>module-info.java</code>, the code will become part of its own named module, and can only see code in <code>java.base</code> and other named modules with are referenced with <code>requires</code> in <code>module-info.java</code>. If the code is compiled without <code>module-info.java</code>, the code will become part of the [[#Unnamed_Module|"unnamed" module]]. | |||
===Example=== | |||
<syntaxhighlight lang='groovy'> | |||
module my.module { | |||
// all directives are optional | |||
requires other.module.a, other.module.b; | |||
} | |||
</syntaxhighlight> | |||
===Module Descriptor Elements=== | |||
====<span id='Module_Name'></span><code>module</code> | Module Name==== | |||
The name of the module. The naming rules are similar to those that apply for packages. Does are allowed, dashes are not. | |||
====<span id='Dependencies'></span><code>requires</code> | Dependencies==== | |||
A list of other modules this module depends on. The dependencies are declared using the keyword <code>requires</code>: | |||
<syntaxhighlight lang='groovy'> | |||
module my.module { | |||
requires other.module.a; | |||
} | |||
</syntaxhighlight> | |||
<code>requires</code> declares at the same time a compile-time and runtime dependency on the specified modules. All public types exported from a dependency are accessible by the module requiring them. | |||
Compile-time dependencies are created by using the <code>requires static</code> keywords. | |||
<syntaxhighlight lang='groovy'> | |||
module my.module { | |||
requires static other.module.b; | |||
} | |||
</syntaxhighlight> | |||
If we want the declared dependencies to bring in transitively their dependencies, use <code>requires transitive</code> keywords: | |||
<syntaxhighlight lang='groovy'> | |||
module my.module { | |||
requires transitive other.module.c; | |||
} | |||
</syntaxhighlight> | |||
====<span id='Public_Packages'></span><code>exports</code> | Public Packages==== | |||
A list of packages that will be accessible from the outside the module. If a package is not listed, it is by default private and it will not be accessible from outside the module. The same is true for [[#Reflection|reflection]], reflection cannot be used unless the package is declared as public. | |||
<font color=darkgray>TODO <code>exports</code>: | |||
* https://www.baeldung.com/java-9-modularity#4-exports | |||
* https://www.baeldung.com/java-9-modularity#5-exports--to | |||
* TODO: <code>qualified exports</code> | |||
</font> | |||
====Services Offered==== | |||
The definition of service implementations that can be consumed by other modules. | |||
<font color=darkgray>TODO <code>provides ... with </code>: | |||
* https://www.baeldung.com/java-9-modularity#7-provides--with | |||
</font> | |||
====Services Consumed==== | |||
The definition of services the module consumes. | |||
<font color=darkgray>TODO <code>uses</code>: | |||
* https://www.baeldung.com/java-9-modularity#6-uses | |||
</font> | |||
====<span id='Reflection'></span>Reflection Permissions==== | |||
Explicitly allows other classes to use reflection to access private members of a package. | |||
<font color=darkgray>TODO <code>open</code>, <code>opens</code>, <code>opens ... to</code>: | |||
* https://www.baeldung.com/java-9-modularity#8-open | |||
* https://www.baeldung.com/java-9-modularity#9-opens | |||
* https://www.baeldung.com/java-9-modularity#9-opens | |||
* https://www.baeldung.com/java-9-modularity#visibility | |||
</font> | |||
==Package== | |||
A module package is identical with a regular Java package. While writing a module, code is organized internally in packages just like before Java 9. Packages are used to determine what code is publicly accessible outside the module. | |||
==Resource== | |||
Each module encapsulates its resources like configuration files and media. | |||
= | ==<span id='Module_Path'></span>Modulepath== | ||
All the code on the modulepath lives in their own "named" modules. Named modules are only found via the modulepath. | |||
The JRE is always on the modulepath, so its internal code cannot be accessed from code on the classpath. | |||
To specify the modulepath, use: | |||
= | <syntaxhighlight lang='bash'> | ||
java -p|--module-path <column-separated-list-of-directories-where-each-directory-is-a-directory-of-modules> ... | |||
</syntaxhighlight> | |||
==Package Relationship to Modules== | ==Package Relationship to Modules== | ||
Line 16: | Line 110: | ||
A package can only be accessed from one module. Hierarchical packages are treated as separate, so "java.util" and "java.util.logging" can exist in different modules. Only public fields and methods are accessible in the code of exported packages of other modules. | A package can only be accessed from one module. Hierarchical packages are treated as separate, so "java.util" and "java.util.logging" can exist in different modules. Only public fields and methods are accessible in the code of exported packages of other modules. | ||
= | ==Classpath== | ||
* | All the code from classpath lives together in the "unnamed" module. | ||
=Operations= | |||
Various module-related operations are exposed by the JVM via module options, described below: | |||
==List Modules== | |||
List observable modules and exit. | |||
<syntaxhighlight lang='java'> | |||
java --list-modules | |||
</syntaxhighlight> | |||
<code>java.base</code> will always be part of it, but many more are usually available: | |||
<syntaxhighlight lang='text'> | |||
java.base@11.0.10 | |||
java.compiler@11.0.10 | |||
java.datatransfer@11.0.10 | |||
java.desktop@11.0.10 | |||
java.instrument@11.0.10 | |||
java.logging@11.0.10 | |||
java.management@11.0.10 | |||
java.management.rmi@11.0.10 | |||
java.naming@11.0.10 | |||
java.net.http@11.0.10 | |||
java.prefs@11.0.10 | |||
java.rmi@11.0.10 | |||
java.scripting@11.0.10 | |||
java.se@11.0.10 | |||
java.security.jgss@11.0.10 | |||
java.security.sasl@11.0.10 | |||
java.smartcardio@11.0.10 | |||
java.sql@11.0.10 | |||
java.sql.rowset@11.0.10 | |||
java.transaction.xa@11.0.10 | |||
java.xml@11.0.10 | |||
java.xml.crypto@11.0.10 | |||
jdk.accessibility@11.0.10 | |||
jdk.aot@11.0.10 | |||
jdk.attach@11.0.10 | |||
jdk.charsets@11.0.10 | |||
jdk.compiler@11.0.10 | |||
jdk.crypto.cryptoki@11.0.10 | |||
jdk.crypto.ec@11.0.10 | |||
jdk.dynalink@11.0.10 | |||
jdk.editpad@11.0.10 | |||
jdk.hotspot.agent@11.0.10 | |||
jdk.httpserver@11.0.10 | |||
jdk.internal.ed@11.0.10 | |||
jdk.internal.jvmstat@11.0.10 | |||
jdk.internal.le@11.0.10 | |||
jdk.internal.opt@11.0.10 | |||
jdk.internal.vm.ci@11.0.10 | |||
jdk.internal.vm.compiler@11.0.10 | |||
jdk.internal.vm.compiler.management@11.0.10 | |||
jdk.jartool@11.0.10 | |||
jdk.javadoc@11.0.10 | |||
jdk.jcmd@11.0.10 | |||
jdk.jconsole@11.0.10 | |||
jdk.jdeps@11.0.10 | |||
jdk.jdi@11.0.10 | |||
jdk.jdwp.agent@11.0.10 | |||
jdk.jfr@11.0.10 | |||
jdk.jlink@11.0.10 | |||
jdk.jshell@11.0.10 | |||
jdk.jsobject@11.0.10 | |||
jdk.jstatd@11.0.10 | |||
jdk.localedata@11.0.10 | |||
jdk.management@11.0.10 | |||
jdk.management.agent@11.0.10 | |||
jdk.management.jfr@11.0.10 | |||
jdk.naming.dns@11.0.10 | |||
jdk.naming.ldap@11.0.10 | |||
jdk.naming.rmi@11.0.10 | |||
jdk.net@11.0.10 | |||
jdk.pack@11.0.10 | |||
jdk.rmic@11.0.10 | |||
jdk.scripting.nashorn@11.0.10 | |||
jdk.scripting.nashorn.shell@11.0.10 | |||
jdk.sctp@11.0.10 | |||
jdk.security.auth@11.0.10 | |||
jdk.security.jgss@11.0.10 | |||
jdk.unsupported@11.0.10 | |||
jdk.unsupported.desktop@11.0.10 | |||
jdk.xml.dom@11.0.10 | |||
jdk.zipfs@11.0.10 | |||
</syntaxhighlight> | |||
==Describe a Module== | |||
The command displays the content of the module: | |||
* [[#Public_Packages|public packages]], as listed under the <code>exports</code> keyword in the module descriptor. | |||
* [[#Services_Consumed|Services consumed]] (<code>uses</code>) | |||
* [[#Services_Offered|Services offered]] (<code>provides</code>). | |||
* Included packages. | |||
<syntaxhighlight lang='bash'> | |||
java -d|--describe-module java.base | |||
</syntaxhighlight> | |||
==Export a Package to a Module== | |||
{{Internal|Ecj#Java_9_Module_Configuration|ecj | Java 9 Module Configuration}} |
Latest revision as of 00:23, 20 May 2021
External
- https://www.baeldung.com/java-9-modularity
- https://www.oracle.com/corporate/features/understanding-java-9-modules.html
- https://www.infoq.com/presentations/java-9-modules
Internal
Concepts
Module
A module is a group of closely related Java packages and resources, shipped together with a module descriptor file module-info.java. A module can be thought of as a package of Java packages. Modules are exposed to the JVM on the modulepath. Modules can be distributed as JARs or as "exploded" compiled projects. When distributed as JARs, there could be just one module per JAR file - each module should be bundled as a separate JAR.
Module Types
System Module
A system module is a named module available with the JDK. They can be listed with java --list-modules
See List Modules below. The system modules are split in at least two major groups: java
, which contain the implementation classes for the core SE Language Specification, and jdk
, which contains code needed by the JDK.
Application Module
Custom modules we usually build. They are named and defined in module-info.java descriptor included in the artifact JAR.
Automatic Module
For JARs created before Java 9, code will get a module name derived from the JAR file name if an existing JAR that was not built as a module is added to modulepath. Automatic modules have full read access to every other module loaded from the modulepath.
Unnamed Module
The "unnamed" module contains code compiled without a module-info.java descriptor and exposed to the JVM on classpath. This is a catch-all module introduced to maintain compatibility with pre-Java 9 artifacts. The "unnamed" module code can see by default all other code in the "unnamed" and java.base
modules, and modules in the java.se
root module. That means if no module-info.java
is present in the project, everything should still work as in Java 8. For this case, dependencies should be continued to be put on the classpath, not on modulepath.
Root Module
ALL-UNNAMED
Module Descriptor module-info.java
module-info.java
is file that represents a module descriptor. If the code is compiled with a module-info.java
, the code will become part of its own named module, and can only see code in java.base
and other named modules with are referenced with requires
in module-info.java
. If the code is compiled without module-info.java
, the code will become part of the "unnamed" module.
Example
module my.module {
// all directives are optional
requires other.module.a, other.module.b;
}
Module Descriptor Elements
module
| Module Name
The name of the module. The naming rules are similar to those that apply for packages. Does are allowed, dashes are not.
requires
| Dependencies
A list of other modules this module depends on. The dependencies are declared using the keyword requires
:
module my.module {
requires other.module.a;
}
requires
declares at the same time a compile-time and runtime dependency on the specified modules. All public types exported from a dependency are accessible by the module requiring them.
Compile-time dependencies are created by using the requires static
keywords.
module my.module {
requires static other.module.b;
}
If we want the declared dependencies to bring in transitively their dependencies, use requires transitive
keywords:
module my.module {
requires transitive other.module.c;
}
exports
| Public Packages
A list of packages that will be accessible from the outside the module. If a package is not listed, it is by default private and it will not be accessible from outside the module. The same is true for reflection, reflection cannot be used unless the package is declared as public.
TODO exports
:
- https://www.baeldung.com/java-9-modularity#4-exports
- https://www.baeldung.com/java-9-modularity#5-exports--to
- TODO:
qualified exports
Services Offered
The definition of service implementations that can be consumed by other modules.
TODO provides ... with
:
Services Consumed
The definition of services the module consumes.
TODO uses
:
Reflection Permissions
Explicitly allows other classes to use reflection to access private members of a package.
TODO open
, opens
, opens ... to
:
- https://www.baeldung.com/java-9-modularity#8-open
- https://www.baeldung.com/java-9-modularity#9-opens
- https://www.baeldung.com/java-9-modularity#9-opens
- https://www.baeldung.com/java-9-modularity#visibility
Package
A module package is identical with a regular Java package. While writing a module, code is organized internally in packages just like before Java 9. Packages are used to determine what code is publicly accessible outside the module.
Resource
Each module encapsulates its resources like configuration files and media.
Modulepath
All the code on the modulepath lives in their own "named" modules. Named modules are only found via the modulepath.
The JRE is always on the modulepath, so its internal code cannot be accessed from code on the classpath.
To specify the modulepath, use:
java -p|--module-path <column-separated-list-of-directories-where-each-directory-is-a-directory-of-modules> ...
Package Relationship to Modules
A package can only be accessed from one module. Hierarchical packages are treated as separate, so "java.util" and "java.util.logging" can exist in different modules. Only public fields and methods are accessible in the code of exported packages of other modules.
Classpath
All the code from classpath lives together in the "unnamed" module.
Operations
Various module-related operations are exposed by the JVM via module options, described below:
List Modules
List observable modules and exit.
java --list-modules
java.base
will always be part of it, but many more are usually available:
java.base@11.0.10
java.compiler@11.0.10
java.datatransfer@11.0.10
java.desktop@11.0.10
java.instrument@11.0.10
java.logging@11.0.10
java.management@11.0.10
java.management.rmi@11.0.10
java.naming@11.0.10
java.net.http@11.0.10
java.prefs@11.0.10
java.rmi@11.0.10
java.scripting@11.0.10
java.se@11.0.10
java.security.jgss@11.0.10
java.security.sasl@11.0.10
java.smartcardio@11.0.10
java.sql@11.0.10
java.sql.rowset@11.0.10
java.transaction.xa@11.0.10
java.xml@11.0.10
java.xml.crypto@11.0.10
jdk.accessibility@11.0.10
jdk.aot@11.0.10
jdk.attach@11.0.10
jdk.charsets@11.0.10
jdk.compiler@11.0.10
jdk.crypto.cryptoki@11.0.10
jdk.crypto.ec@11.0.10
jdk.dynalink@11.0.10
jdk.editpad@11.0.10
jdk.hotspot.agent@11.0.10
jdk.httpserver@11.0.10
jdk.internal.ed@11.0.10
jdk.internal.jvmstat@11.0.10
jdk.internal.le@11.0.10
jdk.internal.opt@11.0.10
jdk.internal.vm.ci@11.0.10
jdk.internal.vm.compiler@11.0.10
jdk.internal.vm.compiler.management@11.0.10
jdk.jartool@11.0.10
jdk.javadoc@11.0.10
jdk.jcmd@11.0.10
jdk.jconsole@11.0.10
jdk.jdeps@11.0.10
jdk.jdi@11.0.10
jdk.jdwp.agent@11.0.10
jdk.jfr@11.0.10
jdk.jlink@11.0.10
jdk.jshell@11.0.10
jdk.jsobject@11.0.10
jdk.jstatd@11.0.10
jdk.localedata@11.0.10
jdk.management@11.0.10
jdk.management.agent@11.0.10
jdk.management.jfr@11.0.10
jdk.naming.dns@11.0.10
jdk.naming.ldap@11.0.10
jdk.naming.rmi@11.0.10
jdk.net@11.0.10
jdk.pack@11.0.10
jdk.rmic@11.0.10
jdk.scripting.nashorn@11.0.10
jdk.scripting.nashorn.shell@11.0.10
jdk.sctp@11.0.10
jdk.security.auth@11.0.10
jdk.security.jgss@11.0.10
jdk.unsupported@11.0.10
jdk.unsupported.desktop@11.0.10
jdk.xml.dom@11.0.10
jdk.zipfs@11.0.10
Describe a Module
The command displays the content of the module:
- public packages, as listed under the
exports
keyword in the module descriptor. - Services consumed (
uses
) - Services offered (
provides
). - Included packages.
java -d|--describe-module java.base