In Java 9: Weak modules we discussed the need for and proposal to create ‘weak modules’. In order to be accessible to another module B, code in module A must be exported. However some frameworks, such as dependency injection, require access to members of non-exported types of other modules.

To date, there have been three major proposals to try and tackle this issue. We caught up with Mark Reinhold at Devoxx BE 2016: “This has been a really tough nut to crack in the design of the module system. Strong encapsulation means that by default, all the internals of a module are strongly encapsulated in a way that’s enforced in a very deep sense in the language and the virtual machine. But of course sometimes you actually want things to be exposed for reflection at runtime by frameworks like Hibernate…” So strong encapsulation needs to be preserved at compile time, but not at runtime.

Open Modules

The latest proposal, Open Modules, “looks like it could be a winner”. “Open” in this sense is similar to “expose”.

To define an open module the modifier ‘open’ is used:

open module foo.bar {
   exports com.foo.bar;
   requires hibernate.core;
   requires hibernate.entitymanager;
}

Copyright © 2016, Oracle and/or its affiliates.
All rights reserved.

It should make the module internals accessible at run time by reflection-based frameworks, but at compile time it is not exported. At run time all elements are accessible via the core refection API, including non-public elements. Packages within the open module can still be exported explicitly for use at compile time.
So in the example above, all elements of all packages are available for deep reflection at run time, but only the public and protected types of com.foo.bar are accessible at compile time.

Opening packages in normal modules

Specific packages in normal modules can be ‘opened’, so that only that package is available for deep reflection at run time:

module foo.bar {
   exports com.foo.bar;
   opens com.foo.bar.model;
   requires hibernate.core;
   requires hibernate.entitymanager;
}


Copyright © 2016, Oracle and/or its affiliates.
All rights reserved.

Here only com.foo.bar is accessible at compile time.

Transitive

As in the weak modules proposal, the requires public syntax will be renamed to requires transitive. Transitive here means – the module requires the readability of the required module. Readability means: when module A depends on module B, and can refer to types in module B, module B is readable by module A.

For example:

module foo.bar {
   exports com.foo.bar;
   requires transitive java.sql;
}

Copyright © 2016, Oracle and/or its affiliates.
All rights reserved.

Means – foo.bar needs to read and refer to types in java.sql.

Solving the Problem

We chatted with Mark Reinhold at Devoxx BE 2016 about the open modules proposal, as well as the need to encapsulate internal APIs like sun.misc.Unsafe.

Further reading

The open modules proposal

Varieties of reflective access

The State of the Module System

The Voxxed Java 9 series

How do you solve a problem like Java 9 modules and reflective access?

| Java Language| 3,479 views | 0 Comments
About The Author
- Katharine is a Java developer by trade, turned Community & Content Manager for Voxxed. Helping developers learn and share knowledge. Contact me at kbe@voxxed.com with any news, articles or tutorials.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>