The JNILoader allows dynamic loading of bundled native libraries into
a running JVM based on the runtime platform. It canonicalizes the
operating system and architecture based on the values of the System
properties os.name and os.arch, then looks for a zip archive,
${libName}-${os}-${arch}, on the classpath and extracts its contents
to a temporary directory. The temporary directory, and any subdirectories
found in the archive, are added to the java.library.path and the cached
paths are cleared so the JVM reconstructs them the next time System.loadLibrary()
is called.
windowslinuxdarwinsolariscygwinmingwmsysOTHER
Other operating systems, such as HP-UX, AIX, etc. can be supported by using
the lowercased value of os.name on that platform with all non-word (\W)
characters removed as the ${os} portion of the archive name.
x86, Intel x86x86_64, Intel x86 (64-bit)ia64, Itaniumis64_32, Itanium (32-bit mode)ppc, PowerPCppc64, PowerPC (64-bit)sparc, SPARCsparcv9, SPARC (64-bit)
These OS/Architecture combinations are the platforms Oracle supports with a downloadable Java 8 Runtime.
windows-x86windows-x86_64linux-x86linux-x86_64solaris-sparcv9solaris-x86_64darwin-x86_64
Native libraries for your supported platforms should be included on the classpath
as a zip archive. The extractor supports subdirectories in the archive and will
add those subdirectories to the java.library.path once they have been created.
Archives for a particular library should be located in the same classpath package
and should be named with a common library base name, the target operating system
and the target architecture: ${basename}-${os}-${arch}.
For example, if you were including the native libraries mylib and extlib-1.2.3
in a Maven based project, your src tree might look like:
- src
- main
- resources
- native
- mylib-windows-x86.zip
- mylib-windows-x86_64.zip
- mylib-linux-x86.zip
- mylib-linux-x86_64.zip
- mylib-darwin-x86_64.zip
- extlib-1.2.3-windows-x86.zip
- extlib-1.2.3-windows-x86_64.zip
- extlib-1.2.3-linux-x86.zip
- extlib-1.2.3-linux-x86_64.zip
- extlib-1.2.3-darwin-x86_64.zip
The default constructor of JNILoader will create a dynamic loader
for the runtime platform that extracts libraries to
${java.io.tmpdir}/jni-loader/${os}/${arch}. Prior to calling
System.loadLibrary() for your libraries, or initializing external
dependencies that rely on bundled libraries, you must call JNILoader.extractLibs(),
providing it the path (in the classpath) containing your archives and the library
prefix you used for the archives. If extractLibs completes successfully, you can
load native code using the standard System calls.
Using the example above, your app initialization might look something like
import com.shankyank.jniloader.JNILoader;
public void initialize() {
JNILoader loader = new JNILoader();
// initialize 'mylib'
loader.extractLibs("/native", "mylib");
// initialize 'extlib'
loader.extractLibs("/native", "extlib-1.2.3");
System.loadLibrary("my_native_lib");
}
The default file extension for native libraries on OS X changed from .jnilib in
Apple's Java 6 implementation to .dylib in OpenJDK 7+. The JNILoader will
ensure that files with both extensions exist when it unbundles a darwin archive,
duplicating the extracted files if the bundle only contains one of the two.
Cygwin, MinGW and Msys are recognized as separate operating systems to support specialized .dll files for those platforms. If an archive bundle for one of those platforms is not found, the loader will look for a Windows bundle for the current architecture and attempt to use those libraries instead.
<dependency>
<groupId>com.shankyank.jni</groupId>
<artifactId>jni-loader</artifactId>
<version>0.1</version>
</dependency>
The JNILoader can be run as a command line utility to display the current
platform, test bundled library extraction or list the standard platforms
described above.
usage: JNILoader -? | -p | -l <lib_package> [-r <path>] [-a] [-o] [-i]
-?,--help Display this help text.
-a,--arch Display canonical architecture name.
-i,--init Extracts the native libraries for the current platform and updates the system library
path.
-l,--lib-name <lib_package> The base name of the library bundles. Bundles must be named ${basename}-${os}-${arch}.zip
-o,--os Display canonical OS name.
-p,--list-platforms List the standard platforms recognized by the JNILoader. Other platforms may be supported
by supplying archive files in the format <basename>-<os>-<arch>.
-r,--resource-path <path> The path, relative to the classpath root, containing the library bundles.