The Java Platform Module System defines a module system for the Java Platform. For more documentation on the implementation, see JEP-261.
Reliable configuration, to replace the brittle, error-prone class-path mechanism with a means for program components to declare explicit dependences upon one another;
This prevents ClassLoader errors such as NoClassDefFoundError
that typically occur at runtime and make applications less reliable.
Strong encapsulation, to allow a component to declare which of its APIs are accessible by other components, and which are not;
JDK internals are now strongly encapsulated, except for critical internal APIs such as sun.misc.Unsafe
(see JEP-396 and JEP-403). datasketches-memory
can no longer access these APIs by default, and requires explicit access.
A module declaration is a java file (typically module-info.java
) that explicitly defines a dependency graph.
In the datasketches-memory-java9
maven submodule root, the following module declaration has been added:
module org.apache.datasketches.memory { requires java.base; requires java.logging; requires jdk.unsupported; exports org.apache.datasketches.memory; exports org.apache.datasketches.memory.internal to org.apache.datasketches.memory.tests; }
This declaration explicitly defines the dependencies for datasketches-memory
, as well as the external API. The org.apache.datasketches.internal
package is now inaccessible to the end user, providing better encapsulation.
The module declaration above makes provision for unit testing. The org.apache.datasketches.internal
package is not accessible to the end user, but is accessible to the org.apache.datasketches.memory.tests
module:
module org.apache.datasketches.memory.tests { requires java.base; requires org.testng; requires org.apache.datasketches.memory; }
Some dependencies are encapsulated by default, and this causes compilation to fail for Java versions 9 and above. These dependencies can be made accessible at compile time through the use of the add-exports
compiler argument. This argument allows one module to access some of the unexported types of another module. Datasketches memory has come to depend on several internal APIs and therefore requires special exposition.
For example, in order to compile the datasketches-memory-java9
submodule, the following compiler arguments are added to the Maven compiler plugin in the module's pom.xml file:
<compilerArgs> <arg>--add-exports</arg> <arg>java.base/jdk.internal.ref=org.apache.datasketches.memory</arg> </compilerArgs>
Reflection is used by the datasketches memory library in cases where fields and methods that do not have public
visibility in a class. Reflective access requires additional arguments to be provided by the user at runtime, in order to use the datasketches-memory
JPMS module in Java versions 9 and above.
The following runtime arguments should be provided when using the library:
--add-opens java.base/java.nio=org.apache.datasketches.memory \ --add-opens java.base/jdk.internal.misc=org.apache.datasketches.memory \ --add-opens java.base/jdk.internal.ref=org.apache.datasketches.memory
Java 8 does not support module declarations and the JPMS module system. However, support is retained for Java 8 users by only including the compiled declaration (module-info.class
) in the datasketches-memory
multi-release JAR for Java9 and above.