Project Jigsaw: Supporting modules with platform specific classes or native code
This page outlines our approach to supporting modules with platform specific classes and/or native code. The term "platform" here is intended to cover operating system and architecture, for example windows-x64 or solaris-sparc. It may also indicate the EABI or processor features, for example linux-armv5-sflt.
Our proposal is to allow modules be platform specific. That is, a module may contain classes, native libraries, and/or other files/resources that are specific to one platform. The majority of modules are likely to be platform independent (noarch). Many of the modules that make up the JDK will be platform specific.
The approach does not preclude cases where a developer decides to split a module into its shared and platform specific parts (see Alternatives). Where the platform specific part is required and is significant, then it may be simpler to combine into one platform specific module.
The main alternative that we examined was so called "Fat/Universal" modules. In this approach a module may contain classes and/or native libraries for more than one platform. Issues with this approach are:
- It would require rev'ing a module version for cases where the module is re-built to include support for a new platform.
- The download size would be a concern for cases where many platforms are supported and/or the platform specific code is large.
- The approach is very unsuited to the JDK. Only about 2% of the JDK classes are platform specific but it contains several large native libraries and other platform specific files.
- The approach is not "build friendly". To build the module requires that the files for all platforms be available or requires adding to the module incrementally.
OSGi appears to have support for universal modules by means of a Bundle-NativeCode header. It requires further investigation to know if their solution is limited to native libraries or whether it supports platform specific classes and other files too.
We also examined the approach where a module is split into "shared" and platform specific modules. Module "foo" may require (or optionally require) "foo-platform-specific" for example. This approch is not precluded by the solution proposed.
One issue with this approach is that it wouldn't allow the platform specific module to be solely a native library. Instead it would minimally require a shim that loads the native library and invokes the native methods (the need for the shim stems arises because module A will not load native libraries located in module B).
JDK modules in the module library
The current module image places the native libraries for the JDK modules in the image's lib directory. We intend to change this so that the JDK modules are organized in the same way as application modules. For example, the native libraries for the base/boot module will be located in jdk.boot/8.0/lib.
This layout assumes that we are not required to have both 32-bit and 64-bit binaries in the same JDK image (as is currently done on Solaris with the legacy image).
bin directory will remain so that java and
other commands can be launched from $JAVA_HOME/bin.
Moving to the layout requires addressing several dependency issues:
- Several native libraries depend on libjava.so because of the common utility/JNU functions. We may need to link these into one of libraries of each module that requires them (an initial prototype using -rpath hackery but this is not transportable to Windows)
- There are several specific cases that require attention, for example librmi.so contains a native method that depends on libjvm.so, SCTP is tightly bound to libnio in the base module.
Items that require further investigation
- Need to decide if the ModuleFileHeader should include a field to identify the platform or should we rely solely on the file/directory to identify the platform?
- The current requirements specify that a native module in a Java module may have a native dependency on a native mode in some other module or "elsewhere in the target platform". This is a challenge because not all platforms support a -rpath equivalent. Even if supported then it bakes the module library format into the native library. We need to investigate if this requirement can be reconsidered. An alternative solution is to provide anative API to allow native libraries access to native libraries in other modules.
- A module may require a native package be installed and so integration with the native packaging system. This needs to be investigated as a separate piece of work.