JNA UnsatisfiedLinkError - works when I set java.library.path to a bogus value
java, java-native-interface, jna
Solution
The root problem is that there is an older version of JNA installed on the system:
$ dpkg -l | grep -i jna
ii libjna-java 3.2.7-4 Dynamic access of native libraries from Java without JNI
JNA starts up by trying to load its bootstrap native library. It searches for this in various places, as described in the documentation.
The problem is fixed by using the `-Djna.nosys=true` flag, which forces JNA to load the native library from your `jna.jar`, not from the system.
Setting the `java.library.path` to a nonsense value has a similar side-effect - it overwrites the normal `java.library.path`, preventing the system version of JNA from being loaded, and falling back on the version from your local `jna.jar`.
The debug setting `-Djna.debug_load=true` is also useful for diagnosing JNA problems.
Problem
Using JNA 4.0.0, on Linux, I am trying to load a native library (`libmean.so`), which is in the `lib` subdirectory (the library is just a trivial example that calculates the mean of two numbers). I run the following code (within Eclipse), with `-Djna.library.path=lib` set in the run configuration. ``` import com.sun.jna.Library; import com.sun.jna.Native; public class Mean { public interface MeanLib extends Library { MeanLib INSTANCE = (MeanLib) Native.loadLibrary("mean", MeanLib.class); double mean(double a, double b); } public static void main(String[] args) { double result = MeanLib.INSTANCE.mean(1.0, 3.0); System.out.println(result); } } ``` But this fails with the following exception: ``` Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't obtain updateLastError method for class com.sun.jna.Native at com.sun.jna.Native.initIDs(Native Method) at com.sun.jna.Native.<clinit>(Native.java:139) at com.sun.jna.examples.Mean$MeanLib.<clinit>(Mean.java:64) at com.sun.jna.examples.Mean.main(Mean.java:72) ``` Through trial-and-error, I have discovered that the code starts working if I also set `java.library.path`. However, it works regardless of the value of this property. For example, I can set `-Djava.library.path=xxxxxxx` and it continues to work. An empty value also works. What is going on?