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-java11
maven submodule source 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 11 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-java11
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 11+, 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 Java11 and above.