2

I'm able to run a program from the commmand line by typing "java main" where main.java and main.class are in the same directory as well as any related classes. This runs fine. When I try to run the same program in Eclipse I get Unsatisfied link errors. I think this is related to the JVM being used. I think that the command line java call is using a different JVM then eclipse. How can you specify which JVM java uses on the command line?

I'm getting an UnsatisfiedLinkError when I run a program in Eclipse that uses native libraries.

This isn't a typical "cannot find...." link error I believe it has actually found the file but there is some other problem.

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.me.this.MyClass.MyMethod(Ljava/lang/String;)I

You can see that if it just could not find the shared library it would say something like:

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

So I believe it is finding the file.

Some other issues that are relavent are the fact that if i run the program from the command line instead of in eclipse it finds the .so and runs the program perfectly. Also I had this program running before in a different Eclipse that was using an older 1.6 JVM. I've tried to use that in this eclipse but it hasn't helped.

Is this a problem finding the .so shared file? Or something completely different like I'm using the wrong JVM. I used strace on the java command line program and it appears it's using the new 1.7jdk the same one I'm using now in Eclipse and it will not work.

The .so is in /usr/lib64 and I've also created a -Djava.library.path=... entry in the vm arguments for the run configuration just in case.

I added these try catch around the load:

static
    {
        try{
            System.loadLibrary("MyAwesomeLibrary");
            System.out.println("MyAwesomeLibrary library loaded \n");
        }
        catch(UnsatisfiedLinkError e){
            System.out.println("Did not load library");
            e.printStackTrace();
        }

    }

And I get:

MyAwesomeLibrary library loaded 

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.me.this.MyClass.MyMethod(Ljava/lang/String;)I
    at com.me.this.MyClass.MyMethod(Native Method)
    at com.me.this.Main.main(Main.java:8)

It's being called froma main class that looks like this:

public class Main
{
        public static void main( String[] args )
        {
                ClassThatContainsLoadedLIbrary x = new ClassThatContainsLoadedLibrary();
                int y = x.Ping( "thisaddress" );

So it appears that it's loading...at least it's getting to the print statement without link errors. the UnsatisfiedLink errors when it actually triest to use the library.

I've been working on this problem for weeks so would really appreciate it if some one had some insight into this. Thanks.

Randnum
  • 1,360
  • 4
  • 32
  • 48

3 Answers3

1

Look at this: http://docs.oracle.com/javase/7/docs/api/java/lang/UnsatisfiedLinkError.html.

Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native.

The problem is not with the JVM per se, but with the JVM being unable to find your native libraries. You need to specify the path where the native libraries are stored. This can be done by adding the following as an argument to your JVM in eclipse:

-Djava.library.path=...

Here, take a look at this: http://mindprod.com/jgloss/runerrormessages.html#UNSATISFIEDLINKERROR

  • If you get the error after the class containing the native method is safely loaded, when you invoke a native method, make sure you generated your *.h file with the fully qualified javah.exe -jni -o mouse.h com.mindprod.mouse.Mouse and not simply javah Mouse
  • If you get the error after the class containing the native method is safely loaded, when you invoke a native method, check that the *.cpp method signatures exactly match those in the *.h file. You should see method names like this: Java_com_mindprod_mouse_Mouse_GetMousePosition that start with the word Java and contain the package, class and method name all strung together. Make sure you remembered to implement all the methods.
  • You need to regenerate the *.h and recompile the *.c file if you change the package name.
  • You should probably go through this list to make sure you're doing all the things correctly.

    Dawood
    • 5,106
    • 4
    • 23
    • 27
    • Thank you, I'm new to using native methods. the actual unsatisfied link error is listing the native method I'm trying to call in the error itself. Exception in thread "main" java.lang.UnsatisfiedLinkError: com.this.xda.MyClass.MyMethod()[Ljava/lang/String; Even though its specifying the native method do you still think it cannot find the native library or could it be something else. Because it was working in eclipse while using another JVM but when I upgraded to JDK 7 it stopped. And I tried going back to the old JDK and it hasn't helped. – Randnum Feb 01 '12 at 15:19
    • The problem is that it's found the declaration of the native method in your Java code but can't find the implementation in native code (i.e., the library in which this method is implemented). Are you working on the exact same project in Eclipse that you were working on with the previous JDK? It's likely that your previous project configuration had specified the `java.library.path` argument somewhere but the new one hasn't... have you checked that? – Dawood Feb 01 '12 at 19:35
    • I was able to run it on fresh installs of eclipse which was grabbing the JRE found by searching the path which ended up being an older 1.6 version. No other settings were changed and it would "just work". if I put a print statement it does load the library without error. the error comes when it actually tries to use it. – Randnum Feb 01 '12 at 19:39
    • Could you also possibly show the code where you're calling MyMethod() and it's implementation in the native code? – Dawood Feb 01 '12 at 19:45
    • I added the calling class it's just a main function that references the loadedlibrary class and calls one of its methods. I can't show the native class right now as some one else actually wrote that and built the library. I'm implementing it. Again I should stress that this does work from the command line and had worked in some strange Eclipse environment that I can't seem to repeat. I feel like it has something to do with an eclipse setting. Maybe the file is marked read only or something is blocking fully using the library methods. – Randnum Feb 01 '12 at 19:54
    • Do you think it would be work recompiling the .so using a different set of tools from a later version of java? say from the JDK7. using its javah calls? – Randnum Feb 01 '12 at 19:57
    • 1
      That's what I had in mind and was just about to say too.. I don't know with certainty if it'll work but try recompiling the header files with javah and then recompiling the library. – Dawood Feb 01 '12 at 20:04
    • 1
      @Randnum: Look at the edit in my answer. I've added a link that you might find helpful. – Dawood Feb 01 '12 at 20:15
    • Thanks, and that link is not opening for me. I just rebuilt and recompiled under Java 7 tools with the javah etc. I'll repost with the results. – Randnum Feb 01 '12 at 20:25
    • If you can't open that link, I've edited my post to add items from that page that seem relevant to your current problem. Hope this works for you. – Dawood Feb 01 '12 at 20:53
    • That solved it! Thank you! It was the package names that were cuasing the problems. It uses the fully qualified name so either you have to take the packatges out or use those when you create your .h files. – Randnum Feb 01 '12 at 21:11
    • 1
      Good to know that it worked for you. JNI can be a real pain sometimes.. I've had that experience too :) – Dawood Feb 01 '12 at 21:18
    • Yea, hopefully this helps other people. – Randnum Feb 01 '12 at 21:25
    0

    You should use java in your console to find options for java.

    java -version:1.6 MyClass

    msi
    • 2,609
    • 18
    • 20
    0

    Right click your project ----> Java Build Path ---> Libraries tab.

    Then select JRE System library , and click Edit to bring the following screen to configure enter image description here

    Ken Chan
    • 84,777
    • 26
    • 143
    • 172
    • Note after right clicking you have to then click properties. I tried to add in this missing information but my edit got rejected for some reason – Aequitas Dec 15 '15 at 00:57