The Essentials of java9 Series (3) Module System



This article mainly narrates the knowledge points that java9 module system must know.

Modules and modules


Module are mainly divided into the following two types:

  • main module

Module containing the main method, specified by –module or -m

  • root module

Specifies the root module that the module system parses. module dependencies are parsed from the root module and can be specified through-add-modules mod1, mod 2


  • unnamed modules

Java9 supports code written by non-java9 through unnamed modules, so legacy code can be used without upgrading the module system. of course, the best way is to upgrade to the supporting module system.

When the module system needs to load types defined by other modules, it will try to load from the classpath, and if the load is successful, it will be classified as unnamed modules. Unnamed modules declare dependency on all named modules and exports all their own packages, but a named module cannot declare dependency on unnamed modules. If a package is defined in both named and unnamed modules, the package in named is used.

  • automatic modules

It is a bridge between the explicitly declared named module and the jar package under the classpath. it is implicitly created from a jar package without module declaration. the module name is taken from the Automatic-Module-Name attribute in the MANIFEST.MF file or the jar package name (Extract from jar package name according to certain rules)。 So named modules can use it to declare dependencies. (You need to use --module-path to specify the path of these jars when javac is compiled.)

An automatic module declares that it depends on all named and unnamed module, and then exports all package. in addition, it supports transfer dependency on other automatic modules.


Declaration dependency


If a depends on b, b depends on c, and the type returned by the b method is the type in c, then a can also use c if a is required, then a dependency c needs to be declared in a. However, this is very difficult, so java9 has built in a transparent keyword.
When B declares a dependency, it specifies the delivery dependency

module B {
    requires transitive C;
    exports func.b;

In this way, a can use the type of c without displaying the requirements module c.


Declare that this dependency is required at compile time and optional at run time. It is more suitable for frameworks or class libraries, such as jdbc drivers. Only api is required at compile time, and the required specified class library is added at run time. If static is not used, all supported jdbc drivers need to be declared dependent at compile time, which is quite laborious.


Export dependency

Specify visible modules

module A {
    exports modulea.funcB to B;
    exports modulea.funcC to C,D,E;

Specifies that exported modulea.funcB is visible only to module b.
Specifies that the exported modulea.funcC is only visible to the c, d, and e modules

open package

module demo {
    opens func1;
    opens func2 to func3;

Allow (specify modules) to use reflective access at runtime in module declarations

open module

The open module is only available at compile time for the specified export module, but all package reflections are allowed at runtime (Include private types and members)。

Open syntax is mainly used for backward compatibility, and many legacy codes use reflection.

5.service loader

It is mainly described in which service interface this module is to use or which service implementation is provided.


The interface used to declare the required service so that the ServiceLoader.load method can be used to load the service provider in the dependency.

module com.demo.consumer {

Uses here indicates that the module needs to use/consume the SortService interface.

provides with

module service.sort.bubble {
    requires service.sort;
    provides with sort.impl.bubble.BubbleSort;

This module uses providers and with to declare that it is the service provider of SortService, so that the module system can know that this module provides the implementation of this interface.

Note that the implementation class exports is not required here

View module description

➜  ~ java -d java.logging
exports java.util.logging
requires java.base mandated
provides jdk.internal.logger.DefaultLoggerFinder with sun.util.logging.internal.LoggingProviderImpl
contains sun.util.logging.internal
contains sun.util.logging.resources

Contains: This part is the part included in the module but not exported (internal)

Mandated:java.lang,, java.util, etc. are all in this java.base module. it is the foundation of other modules. there is no special declaration of dependency on it. by default, all modules depend on it. Therefore, when looking at the module description here, you can see that java.base is followed by a mandated, which indicates that this is the default dependency.


The module system declaration module of java9 mainly includes modules, requirements (transitive\static),exports,open(package\module) and service (uses\provides with) and other concepts.