public class NativeLoader extends Object
The library is first extracted to a temporary file, and then loaded with
System.load()
.
The extractor implementation can be replaced, but the default implementation expects to find the library in natives/, with its OS-dependent name. It extracts the library underneath a temporary directory, whose name is given by the System property "java.library.tmpdir", defaulting to "tmplib".
This is complicated by Java's library and version management - specifically "The same JNI native library cannot be loaded into more than one class loader" . In practice this appears to mean "A JNI library on a given absolute path cannot be loaded by more than one classloader" . Native libraries that are loaded by the OS dynamic linker as dependencies of JNI libraries are not subject to this restriction.
Native libraries that are loaded as dependencies must be extracted using the
library identifier a.k.a. soname (which usually includes a major version
number) instead of what was linked against (this can be found using ldd on
linux or using otool on OS X). Because they are loaded by the OS dynamic
linker and not by explicit invocation within Java, this extractor needs to be
aware of them to extract them by alternate means. This is accomplished by
listing the base filename in a META-INF/lib/AUTOEXTRACT.LIST classpath
resource. This is useful for shipping libraries which are used by code which
is not itself aware of the NativeLoader system. The application must call
extractRegistered()
at some suitably early point in its
initialization (before loading any JNI libraries which might require these
dependencies), and ensure that JVM is launched with the LD_LIBRARY_PATH
environment variable (or other OS-dependent equivalent) set to include the
"tmplib" directory (or other directory as overridden by "java.library.tmpdir"
as above).
Constructor and Description |
---|
NativeLoader() |
Modifier and Type | Method and Description |
---|---|
static void |
extractRegistered()
Extract all libraries registered for auto-extraction by way of
META-INF/lib/AUTOEXTRACT.LIST resources.
|
static JniExtractor |
getJniExtractor() |
static void |
loadLibrary(String libName,
String... searchPaths)
Extract the given library from a jar, and load it.
|
static void |
setJniExtractor(JniExtractor jniExtractor) |
public static void loadLibrary(String libName, String... searchPaths) throws IOException
The default jni extractor expects libraries to be in natives/<platform>/ with their platform-dependent name (e.g. natives/osx_64/libnative.dylib).
If natives/ does not exists or does not contain the directory structure,
<platform>/<lib_binary> will be searched in the root,
META-INF/lib/ and searchPaths
.
libName
- platform-independent library name (as would be passed to
System.loadLibrary)searchPaths
- a list of additional paths relative to the jar's root
to search for the specified native library in case it does not
exist in natives/, root or META-INF/lib/IOException
- if there is a problem extracting the jni librarySecurityException
- if a security manager exists and its
checkLink
method doesn't allow loading of the
specified dynamic librarypublic static void extractRegistered() throws IOException
extractRegistered()
at some suitably early point in its
initialization if it is using libraries packaged in this way.IOException
- if there is a problem extracting the librariespublic static JniExtractor getJniExtractor()
public static void setJniExtractor(JniExtractor jniExtractor)
jniExtractor
- JniExtractor implementation to use instead of the
default.Copyright © 2015–2022 SciJava. All rights reserved.