java.lang.UnsatisfiedLinkError no *****.dll in java.library.path java.lang.UnsatisfiedLinkError no *****.dll in java.library.path java java

java.lang.UnsatisfiedLinkError no *****.dll in java.library.path


In order for System.loadLibrary() to work, the library (on Windows, a DLL) must be in a directory somewhere on your PATH or on a path listed in the java.library.path system property (so you can launch Java like java -Djava.library.path=/path/to/dir).

Additionally, for loadLibrary(), you specify the base name of the library, without the .dll at the end. So, for /path/to/something.dll, you would just use System.loadLibrary("something").

You also need to look at the exact UnsatisfiedLinkError that you are getting. If it says something like:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path

then it can't find the foo library (foo.dll) in your PATH or java.library.path. If it says something like:

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V

then something is wrong with the library itself in the sense that Java is not able to map a native Java function in your application to its actual native counterpart.

To start with, I would put some logging around your System.loadLibrary() call to see if that executes properly. If it throws an exception or is not in a code path that is actually executed, then you will always get the latter type of UnsatisfiedLinkError explained above.

As a sidenote, most people put their loadLibrary() calls into a static initializer block in the class with the native methods, to ensure that it is always executed exactly once:

class Foo {    static {        System.loadLibrary('foo');    }    public Foo() {    }}


Changing 'java.library.path' variable at runtime is not enough because it is read only once by JVM. You have to reset it like:

System.setProperty("java.library.path", path);//set sys_paths to nullfinal Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");sysPathsField.setAccessible(true);sysPathsField.set(null, null);

Please, take a loot at: Changing Java Library Path at Runtime.


The original answer by Adam Batkin will lead you to a solution, but if you redeploy your webapp (without restarting your web container), you should run into the following error:

java.lang.UnsatisfiedLinkError: Native Library "foo" already loaded in another classloader   at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715)   at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646)   at java.lang.Runtime.load0(Runtime.java:787)   at java.lang.System.load(System.java:1022)

This happens because the ClassLoader that originally loaded your DLL still references this DLL. However, your webapp is now running with a new ClassLoader, and because the same JVM is running and a JVM won't allow 2 references to the same DLL, you can't reload it. Thus, your webapp can't access the existing DLL and can't load a new one. So.... you're stuck.

Tomcat's ClassLoader documentation outlines why your reloaded webapp runs in a new isolated ClassLoader and how you can work around this limitation (at a very high level).

The solution is to extend Adam Batkin's solution a little:

   package awesome;   public class Foo {        static {            System.loadLibrary('foo');        }        // required to work with JDK 6 and JDK 7        public static void main(String[] args) {        }    }

Then placing a jar containing JUST this compiled class into the TOMCAT_HOME/lib folder.

Now, within your webapp, you just have to force Tomcat to reference this class, which can be done as simply as this:

  Class.forName("awesome.Foo");

Now your DLL should be loaded in the common classloader, and can be referenced from your webapp even after being redeployed.

Make sense?

A working reference copy can be found on google code, static-dll-bootstrapper .