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 dependencies 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; }
This declaration explicitly defines the dependencies for the org.apache.datasketches.memory
module, as well as the external API. The org.apache.datasketches.memory.internal
package is now inaccessible to the end user, providing better encapsulation.
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 un-exported types of another module.
Datasketches Memory depends 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>
When allocating off-heap memory using WritableMemory.allocateDirect(...)
, reflection is used by the Datasketches Memory component to access JVM internal class fields and methods that do not have public
visibility. For JDK 9+, the JPMS requires that the user add additional JVM run-time arguments (add-opens...
, which permit this reflection.
Note that if the user has allocated off-heap memory using ByteBuffer.allocateDirect(...), the DataSketches memory component can still read and write to this memory without these add-opens...
arguments.
See the use Use as a Library and Developer Usage sections in the main README for more details. In addition, examples are provided in the usage examples document.
Java 8 does not support module declarations and the JPMS module system, and no additional runtime arguments are necessary. 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.