What is an open module in Java 9 and how to use it

In order to provide reflective access to your module, Java 9 introduced the open keyword.

You can create an open module by using the open keyword in the module declaration.

An open module grants reflective access to all of its packages to other modules.

For example, if you want to use some framework that heavily relies on reflection, such as Spring, Hibernate, etc, you can use this keyword to enable reflective access for it.

You can enable reflective access for specified packages of your module by using the opens statement in the package declaration:

module foo {
    opens com.example.bar;
}

or by using the open keyword in the module declaration:

open module foo {
}

but keep in mind, that you cannot combine them:

open module foo {
    opens com.example.bar;
}

results with compile-time error.

Hope it helps.


A bit of a background to the directives in question. The Module System states in the Breaking encapsulation section

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 on them. The --add-exports option can be used, at both compile time and run time, to do this.

The command line option is equivalent to for example:-

module java.logging {
    exports java.util.logging;
}

The --add-exports option enables access to the public types of a specified package.


Though thereafter,

It is sometimes necessary to go further and enable access to all non-public elements via the setAccessible method of the core reflection API. The --add-opens option can be used, at runtime, to do this.

This command line option is equivalent to for example:-

module jdk.unsupported  {
   opens sun.misc; 
}

An ordinary named module, by contrast, is defined explicitly with a module declaration as:-

module foo { }

and these are known as explicit modules. Explicit modules can use directives on packages as stated above for example to export/open packages to provide reflective access to their respective public members and classes.


On the other hand, an OPEN module is a

module that does not declare any open packages but the resulting module is treated as if all packages are open.

Such that it grants access at runtime to types in all of the module's packages as if all packages are exported which means bytecode or reflection can be used to access every package's classes or members in all packages. The reflection APIs with setAccessible or MethodHandles.privateLookupIn allow for deep reflection, so in short you can reflect on all members of all classes in all packages. Which also pretty much explains the reason why compiler won't allow both open directives to a package while the module is already open.