Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is an open module in Java 9 and how do I use it?

What is the difference between a module with the open keyword before it and without it? For instance:

open module foo {
}

module foo {
}
like image 602
user8693774 Avatar asked Sep 29 '17 05:09

user8693774


People also ask

How do you use modules in Java?

To set up a module, we need to put a special file at the root of our packages named module-info. java. This file is known as the module descriptor and contains all of the data needed to build and use our new module. We start the module declaration with the module keyword, and we follow that with the name of the module.

What are modules in Java 9?

Defining the Java 9 module. A module is a collection of code, data, and resources. It is a set of related packages and types (classes, abstract classes, interfaces, and more) with code, data files, and some static resources. For example, the module descriptor module-info.

Should I use Java 9 modules?

There is no need to switch to modules. There has never been a need to switch to modules. Java 9 and later releases support traditional JAR files on the traditional class path, via the concept of the unnamed module, and will likely do so until the heat death of the universe.


Video Answer


2 Answers

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.

like image 187
Michał Szewczyk Avatar answered Oct 16 '22 16:10

Michał Szewczyk


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.

like image 20
Naman Avatar answered Oct 16 '22 17:10

Naman