The JNI specification doesn't fully support or specify how to use statically linked native libraries. There are at least two possible uses for this.
1. Native applications that embedded the JRE may wish to use statically linked JNI code rather than dynamically linked libraries.
2. Java applications that are developed for Apple mobile devices where shared libraries are not supported. In this type of platform, the JRE and all of it's supported native code is linked into a single application binary.
At least two problems need to be addressed:
1. The current Java APIs that are used to initiate the loading process and as a result allow the native library entrypoints to be recognized need to be enhanced to support build-in libraries. A Java application wishing to use a build-in JNI library need a mechanism for notifying the VM that this library code is already included in the application image. In this situation, a System.loadLibrary request for a built-in library should avoid the platform native load but process the library as if the load succeeded.
The current JNI specification alludes to this type of support but the current Hotspot VM does not support this behavior. "If the underlying operating system does not support dynamic linking, all native methods must be prelinked with the VM. In this case, the VM completes the System.loadLibrary call without actually loading the library."
2. The JNI_OnLoad and JNI_OnUnload function interface need to be enhanced to
support library specific names since only a single function name can exist within an application. This could be implemented by appending the library name
to these well-known-names. For example libnet.so could use JNI_OnLoad_net,
1. Require that a library specific JNI_Onload function name exists in the executable image for each static library that is included in a Java application.
2. The VM shall be modified to detect the presence of the library specific JNI_OnLoad function and if available, must allow a System.loadLibrary or Runtime.loadLibrary call to succeed without actually loading a shared library.
3. A library specific JNI_OnUnload function can also exist for each statically linked library and will be called when the class loader that called the loadLibrary is garbage collected.
exported external native JNI_OnLoad, JNI_OnUnload
System.load, Runtime.load method SPECIFICATION CHANGE
The System.load and Runtime.load specification descriptions will be change in JDK8 to:
Loads the native library specified by the libname argument. The libname argument must be a fully specified path name.
If a native library called libname is statically linked, then the JNI_OnLoad_libname function exported by the library is invoked. The library name used in the construction of the JNI_OnLoad_libname function must be the name of the library and not contain any path or other platform specific prefix or file name extension.
See the JNI Specification for more details.
Otherwise, the libname argument is mapped to a native library image in an implementation-dependent manner.
The UnsatisfiedLinkError - if either the native library is not statically linked, libname is not a fully specified path or the library does not exist.
System.loadLibrary, Runtime.loadLibrary method SPECIFICATION CHANGE
The System.loadLibrary and Runtime.loadLibrary specification descriptions will be change in JDK8 to:
Loads the native library specified by the libname argument.
If a native library called libname is statically linked, then the JNI_OnLoad_libname function exported by the library is invoked. See the JNI Specification for more details.
Otherwise, the libname argument is loaded from a system library location and mapped to a native library image in an implementation-dependent manner.
The UnsatisfiedLinkError - if either the native library is not statically linked, libname contains a fully specified path or the library does not exist.
JNI SPECIFICATION CHANGE
- A native library may be statically linked with the VM. The manner in which the library and VM image are combined is implementation-dependent.
- A System.loadLibrary or equivalent API must succeed for this library to be considered loaded.
- A library L whose image has been combined with the VM is defined as _statically linked_ if and only if the library exports a function called JNI_OnLoad_L.
- If a _statically linked_ library L exports a function called JNI_OnLoad_L _and_ a function called JNI_OnLoad, the JNI_OnLoad function will be ignored.
- If a library L is _statically linked_, then an invocation of System.loadLibrary("L") or equivalent API causes the VM to invoke the JNI_OnLoad_L function with the same arguments and expected return value as specified for the JNI_OnLoad function.
- A library L that is _statically linked_ will prohibit a library of the same name from being loaded dynamically.
- When the class loader containing a _statically linked_ native library L is garbage collected, the VM will invoke the JNI_OnUnload_L function of the library if such a function is exported.
- If a _statically linked_ library L exports a function called JNI_OnUnLoad_L _and_ a function called JNI_OnUnLoad, the JNI_OnUnLoad function will be ignored.
The JNI version specification will be incremented to JNI_VERSION_1_8.
This new functionality will be supported in JNI_VERSION_1_8 or greater.