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

旧巷老猫 提交于 2019-11-30 11:08:14
Michał Szewczyk

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

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

An open module grants reflective access to all of it's 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 opens statement in package declaration:

module foo {
    opens com.example.bar;
}

or using open keyword in 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!