public class NativeLibraryManager
extends java.lang.Object
Normally, this class operates as a singleton and is accessed through the
static methods verify() and load(). Native
libraries are stored in a native-specific directory within a generic library
directory that is specified using setLibDir(). This must
be set in order to enable the downloading and updating of libraries. If this
is not set, then verify and load will attempt to
find the specified libraries in the system's load library path, but no
attempt will be made to update or load them.
Libraries are specified generically using a name of the form
<basename><versionStr>
where <versionStr> is an optional string of the form ".I.J.K ..."
with I, J, K, etc. being non-negative integers that specify version
numbers. Versions are ordered by comparing these numbers from left to
right, with numbers to the left having priority. For example,
solver.1.3 and solver.1.3.77 both indicate a
library with a basename of solver, with
solver.1.3.77 being the more recent version.
A versioned library name is satisfied by any library whose version
string starts with the same numbers, possibly followed by additional
ones. That is, xxx.I.J is satisfied by xxx.I.J,
xxx.I.J.K, xxx.I.J.K.L, etc., but not by
xxx.I.JK or xxx.I.(J+1). This allows
code to request a library as (say) gdcmjni.3.0.22, so that
patch versions such as gdcmjni.3.0.22.1 can be introduced
without changing the code. Unversioned names are only satisfied by
themselves.
load() resolves a library name as follows. If verify() was previously called (e.g., by the library installer)
for a name with the same basename that satisfies the requested name, then
that name is used. Otherwise, if the library file named exactly is not
present, the most recent satisfying library present is used. Failing that,
an attempt is made to download the exactly named library. verify(), which ensures that a specific library version is installed,
instead tries the download first, using a present satisfying library only
if the download fails.
Generic library names are converted into library file names appropriate
for the current native system. For example, solver.1.3,
would be converted into the following native file names:
libsolver.so.1.3 // Linux libsolver.1.3.dylib // MacOS solver.1.3.dll // Windows
Alternative, it is also possible to specify an actual system-specific
library file name to a verify() or load()
request. In that case, the system type is determined from the name, and the
request is carried out only if this matches the actual current system.
A versioned library can also be given a link with a different
(usually unversioned) file name, using verify(libName,linkName) or load(libName,linkName). This is for support libraries, such as libiomp5.so, that other native libraries reference by a fixed name: the
versioned file (e.g., libiomp5.so.2026.1) is downloaded and
updated as usual, and the link (a symbolic link, or a copy on Windows)
makes it available under the fixed name.
| Modifier and Type | Class and Description |
|---|---|
static class |
NativeLibraryManager.SystemType
Indicates the operating system type.
|
| Modifier and Type | Field and Description |
|---|---|
static int |
UPDATE
Flag to indicate that when checking a library, we see if it matches the
latest version on the server, and if not, download the latest version
from the server.
|
static int |
VERBOSE
Flag to enable messages to be printed to console.
|
| Modifier and Type | Method and Description |
|---|---|
static java.lang.String |
getFileName(java.lang.String libName)
Returns the system-specific file name for the named library.
|
static FileTransferListener |
getFileTransferListener()
Returns the application-specified file transfer listener for this library
manager, if any.
|
static int |
getFlags()
Returns the currently active flags for the library manager.
|
static java.lang.String |
getLibDir()
Returns the main library directory which currently set (or
null if no directory is set). |
static java.lang.String |
getPathName(java.lang.String libName)
Returns the full path name for the specified library file on this
system.
|
static NativeLibraryManager.SystemType |
getSystemType()
Returns the current system type.
|
static NativeLibraryManager.SystemType |
getSystemType(java.lang.String typeName) |
static boolean |
isValidLinkName(java.lang.String libName,
java.lang.String linkName)
|
static boolean |
isValidObsoleteName(java.lang.String name)
Returns true if
name is a valid name for an obsolete native
library (see removeObsoleteLibraries(java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>)). |
static boolean |
libraryMatchesSystem(java.lang.String libName)
Returns true if the indicated native library name matches the current
system.
|
static void |
load(java.lang.String libName)
Loads a Java native library specified by libName.
|
static void |
load(java.lang.String libName,
java.lang.String linkName)
Loads a Java native library through a link to it, after first calling
verify(String,String) to make sure that both the library and
the link are present. |
static void |
main(java.lang.String[] args) |
static int |
removeObsoleteLibraries(java.util.Collection<java.lang.String> obsoleteNames,
java.util.Collection<java.lang.String> activeNames)
Removes obsolete native libraries, as with
removeObsoleteLibraries(Collection,Collection,Collection), with
no links other than those created by verify(String,String). |
static int |
removeObsoleteLibraries(java.util.Collection<java.lang.String> obsoleteNames,
java.util.Collection<java.lang.String> activeNames,
java.util.Collection<java.lang.String> linkNames)
Removes obsolete native libraries from the native library directory
for the current system.
|
static int |
removeOlderVersions(java.lang.String libName)
Removes older versions of the indicated native library from the
native library directory.
|
static void |
setFileTransferListener(FileTransferListener l)
Sets a file transfer listener for the library manager, to monitor the
progress of file transfers from the server.
|
static void |
setFlags(int flags)
Sets the currently active flags for the library manager.
|
static void |
setLibDir(java.lang.String libBaseName)
Sets the main library directory which contains the native directory.
|
static void |
setSystemType(NativeLibraryManager.SystemType type)
Explicitly sets the current system type.
|
static int |
verify(java.lang.String libName)
Verifies that the indicated native library is present, downloading or
updating it from the server if necessary.
|
static int |
verify(java.lang.String libName,
java.lang.String linkName)
Verifies that the indicated native library is present, as with
verify(String), and then makes sure that the file linkName in
the native library directory refers to it. |
static boolean |
wildcardMatches(java.lang.String pattern,
java.lang.String str)
Returns true if
str matches pattern, in which each '*'
matches any sequence of characters. |
public static int UPDATE
public static int VERBOSE
public static NativeLibraryManager.SystemType getSystemType(java.lang.String typeName)
public static void setFileTransferListener(FileTransferListener l)
getFileTransferListener()public static FileTransferListener getFileTransferListener()
public static NativeLibraryManager.SystemType getSystemType()
public static void setSystemType(NativeLibraryManager.SystemType type)
public static java.lang.String getFileName(java.lang.String libName)
getFileName ("foo.1.4"); will return
libfoo.so.1.4. See the discussion in the class header for
more information about how the library name is formatted.libName - name of the library.public static void setLibDir(java.lang.String libBaseName)
libBaseName - full path name of the base directory containing
the native library directory.public static java.lang.String getLibDir()
null if no directory is set).public static int verify(java.lang.String libName)
libName - name of the libraryNativeLibraryException - if the required library
is not present and cannot be obtained.public static int verify(java.lang.String libName,
java.lang.String linkName)
verify(String), and then makes sure that the file linkName in
the native library directory refers to it. This allows a versioned
library file (such as libiomp5.so.2026.1) to be found under the
unversioned name (such as libiomp5.so) by which other native
libraries reference it. On Linux and MacOS, linkName is a
symbolic link to the library file; on Windows (or if symbolic links
cannot be created) it is a copy of the library file. If linkName already exists, it is replaced if it does not refer to (or
is not identical to) the library file. Files named by linkName
are never removed by removeOlderVersions(maspack.fileutil.NativeLibraryManager.LibDesc) or removeObsoleteLibraries(java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>).libName - name of the librarylinkName - system-specific file name of the link (see isValidLinkName(java.lang.String, java.lang.String))NativeLibraryException - if the required library
is not present and cannot be obtained, or if the link does not exist
and cannot be created.public static void load(java.lang.String libName,
java.lang.String linkName)
verify(String,String) to make sure that both the library and
the link are present. Loading through the link means the library is
known to the system under the link name. On Windows, this allows
imports of that name by other native libraries to be satisfied by the
loaded library.libName - name of the librarylinkName - system-specific file name of the linkpublic static boolean isValidLinkName(java.lang.String libName,
java.lang.String linkName)
linkName is a valid link name for the library
libName (see verify(String,String)). The link name
must be a system-specific library file name (such as libiomp5.so), with no path separators or wildcards, for a system that
is compatible with the library's, and must differ from the library's
own file name on that system.libName - name of the librarylinkName - name of the linklinkName is validpublic static int removeOlderVersions(java.lang.String libName)
verify()),
and the library name must have a version string. Files are removed if
they correspond to the same library, with a version string that is
lower than the one specified. For example, given the name
TetgenJNI.1.5.1.1 on MacOS, libTetgenJNI.1.5.dylib
would be removed, but not libTetgenJNI.1.6.dylib or libTetgenJNI.dylib. Files that cannot be removed (which can happen on
Windows if they are in use by another process) are left in place and a
warning is printed.libName - name of the librarypublic static boolean wildcardMatches(java.lang.String pattern,
java.lang.String str)
str matches pattern, in which each '*'
matches any sequence of characters.public static boolean isValidObsoleteName(java.lang.String name)
name is a valid name for an obsolete native
library (see removeObsoleteLibraries(java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>, java.util.Collection<java.lang.String>)).public static int removeObsoleteLibraries(java.util.Collection<java.lang.String> obsoleteNames,
java.util.Collection<java.lang.String> activeNames,
java.util.Collection<java.lang.String> linkNames)
obsoleteNames, unless it is one of the libraries in
activeNames or a link (see verify(String,String)).
If the name it matches contains a '*' wildcard, the file is also kept
if it is any version of a library in activeNames. This allows
an unversioned or older file (such as foo.dll) to be removed
by naming it exactly, even when another version (such as foo.1.2.dll) is in use. Obsolete names take two forms:
PardisoJNI.2021.1.1, which
matches the file for that library and version on the current system.
The version string can end in ".*", so that PardisoJNI.2021.*
matches all 2021 versions, and PardisoJNI.* matches all
versions, including an unversioned file.
libiomp5.so, which
matches only on the indicated system. It can contain '*' wildcards,
provided that at least part of the base name precedes the first one
(e.g., libiomp5*.so* but not lib*.so).
obsoleteNames - names of the obsolete librariesactiveNames - names of the libraries in use on the current systemlinkNames - file names of links to libraries in use, which are
kept in addition to those created by verify(String,String)public static int removeObsoleteLibraries(java.util.Collection<java.lang.String> obsoleteNames,
java.util.Collection<java.lang.String> activeNames)
removeObsoleteLibraries(Collection,Collection,Collection), with
no links other than those created by verify(String,String).obsoleteNames - names of the obsolete librariesactiveNames - names of the libraries in use on the current systempublic static boolean libraryMatchesSystem(java.lang.String libName)
public static void setFlags(int flags)
VERBOSE or
UPDATE.getFlags()public static int getFlags()
setFlags(int)public static java.lang.String getPathName(java.lang.String libName)
libName - name of the library.java.lang.IllegalStateException - if the main library directory has
not been set using setLibDir().public static void load(java.lang.String libName)
System.load() that first attempts to locate the library
file, if necessary downloading or updating it from the server. See the
discussion in the class header for more information about how the library
name is formatted, and how libraries satisfying a versioned name are
resolved.libName - name of the library.public static void main(java.lang.String[] args)