Search code examples
javaeclipsenativeunsatisfiedlinkerror

Loading native libraries in java


I have an eclipse project with two classes. The class "SomeClass1" has a native method:

SomeClass1

public class SomeClass1 {
    static {
        System.loadLibrary("libname"); // Load the native library.
    }
    public native void some_method(); // implemented in the library
    // .... other non methods ....
}

The other class "SomeClass2" uses the native method of "SomeClass1". Like:

SomeClass2

public class SomeClass2{
    public static void main(String[] args) {
        SomeClass1 s = new SomeClass1();
        s.some_method();
    }
    // ....other methods....
}

However when it calls that method it throws an error like this:

Exception in thread "main" java.lang.UnsatisfiedLinkError: no libname in java.library.path
....
at java.lang.System.loadLibrary(Unknown Source)
at x.x.x.SomeClass1.<clinit>(SomeClass1.java:128)
at SomeClass2.main(SomeClass2.java:10)

I think the error has something to do with java not knowing where to look for the native library.

Question1 When I use: -Djava.library.path="C:\Users.....\libfolder\" as run argument in eclipse and print the value of: System.getProperty("java.library.path"); I see alot of directories printed but not the directory that I specified in the argument. What am I doing wrong?

Question2 When I do: System.loadLibrary("name"); do I need to call the library "name.so" or "libname.so"?

Question3 If the library would be found but was a 64 bit library while the platform it is loaded on is 32 bit, would it also give a unsatisfiedLinkError or would a different error be given?

Question4 Can I specify the path to the library relative to the projects folder or relative to the file in which the library is loaded?

Hope you are able to answer (some of) my questions.

Grtz Stefan


Solution

  • Question 1:

    You should not add this as a run argument, but as a VM argument. It's not an argument for your program, but for the JVM.

    Question 2:

    (Also @IanRoberts ) : The System.loadLibrary(name) call will automatically derive the name of the actual library from the given name. That means that it will append ".dll" on windows, and use "lib" + name + ".so" on linux. Otherwise, loading a native lib would not be possible in a platform-independent way!

    Question 3:

    In general, the UnsatsfiedLinkError is distressingly common. It's in fact true to say: The UnsatisfiedLinkError does not tell you more than "Something is wrong". You can only hope for the actual error message to be more descriptive, and this would (fortunately) be the case if you had a 32/64bit mismatch - at least on windows:

    • Trying to load a 32bit lib on a 64bit system will cause the message: "Can't load IA 32-bit .dll on a AMD 64-bit platform"
    • Trying to load a 64bit lib on a 32bit system will cause the message: "... is not a valid Win32 application"

    (I'm not sure about the message for other operating systems, though, but your message indicates that the library is just not found, and not that there's a problem with the library itself)

    (Question 4: I'm rather sure that this is possible, but not absolutely sure (and can't try it out) at the moment. In general, the library must be in a path that is visible via the PATH environment variable, or via the java.library.path. In doubt, it should always work then the native libs are in the same directory as where you are starting your program from)