Ustawianie java.library.path w czasie działania programu. Źródło: http://fahdshariff.blogspot.be/2011/08/changing-java-library-path-at-runtime.html
The java.library.path
system property instructs the JVM where to search for native libraries. You have to specify it as a JVM argument using -Djava.library.path=/path/to/lib
and then when you try to load a library using System.loadLibrary("foo"), the JVM will search the library path for the specified library. If it cannot be found you will get an exception which looks like:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
The java.library.path
is read only once when the JVM starts up. If you change this property using System.setProperty, it won't make any difference.
Here is the code from ClassLoader.loadLibrary which shows how the path is initialised:
if (sys_paths == null) {
usr_paths = initializePath("java.library.path");
sys_paths = initializePath("sun.boot.library.path");
}
As you can see from the code above, the usr_paths
variable is only initialised if sys_paths
is null, which will only be once.
So, how can you modify the library path at runtime? There are a couple of ways to do this, both involving reflection. You should only do this if you really have to.
/**
* Sets the java library path to the specified path
*
* @param path the new library path
* @throws Exception
*/
public static void setLibraryPath(String path) throws Exception {
System.setProperty("java.library.path", path);
//If you set sys_paths to null, the library path will be re-initialised when you try to load a library.
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
sysPathsField.setAccessible(true);
sysPathsField.set(null, null);
}
//Instead of having to re-evaluate the entire java.library.path and sun.boot.library.path,
//you can instead append your path to the usr_paths array.
/**
* Adds the specified path to the java library path
*
* @param pathToAdd the path to add
* @throws Exception
*/
public static void addLibraryPath(String pathToAdd) throws Exception{
final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
usrPathsField.setAccessible(true);
//get array of paths
final String[] paths = (String[])usrPathsField.get(null);
//check if the path to add is already present
for(String path : paths) {
if(path.equals(pathToAdd)) {
return;
}
}
//add the new path
final String[] newPaths = Arrays.copyOf(paths, paths.length + 1);
newPaths[newPaths.length-1] = pathToAdd;
usrPathsField.set(null, newPaths);
}