JNI (Java Native Interface): Exception in thread “main” java.lang.UnsatisfiedLinkError: Can’t find dependent libraries

How to fix UnsatisfiedLinkError in JNI

I have never had problems with JNI. In the few situations when I needed it, it just worked. But last week someone asked me for help with his problem. When I tried to reproduce it, I found out that it had spread even to my old JNI programs which worked until 2006!

When running a program that uses a native function the following error occured:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Test.dll: Can't find dependent libraries

It’s obviously a linker problem related to the generation of the .dll file. I have no idea why it occurs now and didn’t occur in the past. Different OS, compiler version, something like that? For some reason both the linker of Visual Studio and the linker of GCC started to think that is was a good idea to replace all method names by some arbitrary name which then cannot be found at runtime.

Fix for GCC

To fix that with GCC, the linker opion --add-stdcall-alias can be used.

gcc -Wl,--add-stdcall-alias -mno-cygwin -shared -I/cygdrive/c/Program\ Files/Java/jdk1.6.0_05/include -I/cygdrive/c/Program\ Files/Java/jdk1.6.0_05/include/win32 -o HelloWorld.dll HelloWorld.c

Fix for Visual C

For Microsoft Visual C Compiler it should theoretically be possible with a linker option as well.

Find out the correct linker option

First compile and link in the usual way that didn’t work. This will create the .dll file which results in the error we are talking about. Then use the dumpbin tool to list the procedure names:

dumpbin HelloWorld.dll /EXPORTS

You will find your procedure name, something like _Java_HelloWorld_print@8. Now try to guess what the name should be. My guess in this case would be Java_HelloWorld_print. This would result in the linker option /EXPORT:Java_HelloWorld_print=_Java_HelloWorld_print@8

Supply the linker option
  1. Use a #pragma comment in the source file:
    #pragma comment(linker, "/EXPORT:Java_HelloWorld_print=_Java_HelloWorld_print@8")

    OR

  2. Split into linking and compiling and provide the option to the linker in the command line, OR
  3. Supply it to the compiler at the end using /link:
    cl -I"C:\Program Files\Java\jdk1.6.0_05\include" -I"c:\Program Files\java\jdk1.6.0_05\include\win32" -MD -LD HelloWorld.c -FeHelloWorld.dll /link /EXPORT:Java_HelloWorld_print=_Java_HelloWorld_print@8

Edit: According to user comments, the -MD option above is wrong and causes the problem described below. Do not use -MD! See MSDN for further information about the -MD option.

Option 3 is probably the easiest. After that dumpbin will show that now there is an additional procedure with the correct name:

dumpbin HelloWorld.dll /EXPORTS

I even compared it with the working .dll I created with GCC (see above), and it looks the same! But it doesn’t work, still getting the same error!

33 Responses to “JNI (Java Native Interface): Exception in thread “main” java.lang.UnsatisfiedLinkError: Can’t find dependent libraries”

  1. Alexandra Niculai says:

    So, I searched a lot, but I found a solution that worked for me. Removing the -MD gives you this:
    cl -Ic:\java\include -Ic:\java\include\win32 -LD HelloWorld.c -FeHelloWorld.dll

    For me, it worked! For the rest, I can’t speak C++ and I don’t know why it happened.

  2. Kai Witte says:

    Thanks Alexandra,

    your insight will help many people! This post gets lots of hits every day :-)

    Kai

  3. Look Out says:

    I have a problem creating a simple Java Application that uses JNI to load a dll that prints the mesage “HelloWorld”.

    The following stages were succesful:
    1. Creating the HelloWorld.java file and compiling it.
    2. Using javah -jni to produce HelloWorld.h (a C/C++ header file)
    3. Coding the HelloWorld.c file and compiling it to get:
    a) HelloWorld.exp, HelloWorld.dll, HelloWorld.lib, HelloWorld.obj

    The stage where I am failing:
    1. Running the Java program using: java HelloWorld at the command line produces the following error:
    Exception in thread “main” java.lang.UnsatisfiedLinkError: HelloWorld.helloWorld
    ()V
    at HelloWorld.helloWorld(Native Method)
    at HelloWorld.main(HelloWorld.java:8)

    C:\>
    For compilation purposes I am using the Microsoft Visual C++ 2008 Express Edition’s command line utility

    What could be the problem with my program

    Thanks in anticipation of the best help you can offer

  4. Kai Witte says:

    Hello,

    is that all the error message you get? Delete the .dll, try again. When it is still the same message, then you know more about the problem. Otherwise you know more as well. Win-win.

    Kai

  5. nethibernate says:

    Thanks Alexandra, your insight really works.
    I got the same problem with Kai. I think it’s not about the procedure name. If you remove the “-MD” option when you link the C file, it can work.

  6. Amaresh says:

    Wow !!
    Thanks so much.

    This topic helped me getting started with Java -> JNI -> DLL.

    Thanks

  7. Manoj says:

    add option “-Wl,–kill-at”

    `–kill-at’
    Specifies that when `dlltool’ is creating the
    exports file it should not append the string
    `@ ‘. These numbers are called
    ordinal numbers and they represent another
    way of accessing the function in a DLL, other
    than by name.

    With this the problem will go away sure shot.

  8. degree says:

    just need to build the helloworld.c following way

    cl -I c:\Java\jdk1.6.0_01\include -I c:\Java\jdk1.6.0_01\include\win32 -LD HelloWorld.c -FeHelloWorld.dll

    Not with -MD option. Java load library functions are not able to load because of -MD option. I think JNI documentations should be updated.

  9. franklin says:

    Exception in thread “main” java.lang.UnsatisfiedLinkError: sendechotohost
    at NativePing.sendechotohost(Native Method)
    at NativePing.getResultForTheHost(NativePing.java:517)
    at NativePing.pingHost(NativePing.java:396)
    at NativePing.pingHost(NativePing.java:422)
    at NativePing.pingHost(NativePing.java:384)
    at NativePing.main(NativePing.java:616)

    In Linux I am getting this error. Can any one explain….

  10. Kai Witte says:

    hello Franklin,

    I’d say either the native binary is not found or it doesn’t contain what you need.

    Did you compile it with gcc –add-stdcall-alias? Did you check out which functions the binary contains? Did it contain sendechotohost? Is it in the runtime PATH?

  11. Ben Hmida says:

    Hi ,
    I m a Phd student and actually, i have the same problem. just, im working wih netbeans, and it is forbidden to install any other software or any things. I m working on from 3 days and the delevered message is
    “run: Exception in thread “main” java.lang.UnsatisfiedLinkError: HelloWorld.print()V
    at HelloWorld.print(Native Method)
    at HelloWorld.main(HelloWorld.java:4)
    Java Result: 1
    BUILD SUCCESSFUL (total time: 0 seconds)”

    I m respecting all the steps, even i tried until now 5 examples and almost the same display error.
    So do any one of u have an idea how to resolve this problem
    NB: i m working with netbeans 6,9 and with jdk1.6.0_20

    Danke

  12. Kai Witte says:

    Hello Ben,

    I’d say that the .dll is not in the PATH and not in the working directory, or that something is wrong with it (like for example in my case).

    It will help to do it without NetBeans, just run from the command line. That’s certainly possible in your environment.

    Kai

  13. Ben Hmida says:

    Hallo
    Das ist ok
    Vielen danke:)

  14. Ben Hmida says:

    Hallo again,
    Actually, my I m improving with JNI, the current problem is related to more than one variables returning. Since the C++ functions return more than one variables, so please, dis any one of you have an ideas how it is possible to recover from java the result of more than one variable ?

    Thanks in advance

  15. I’ ve the same problem

    Exception in thread “main” java.lang.UnsatisfiedLinkError: javacsharptest.JavaCSharpTest.display()V
    at javacsharptest.JavaCSharpTest.display(Native Method)
    at javacsharptest.JavaCSharpTest.main(JavaCSharpTest.java:18)

    I’m working with netbeans6.5
    I want to know how to run from command line

    Please help me

  16. Kai Witte says:

    Hello Saw,

    this exact problem has been discussed here already.

  17. Anand says:

    Hi

    I am getting Exception in thread “main” java.lang.UnsatisfiedLinkError:
    when i try to run a native method accessing a .dll in a Dynamic web Project

    But i am able to the same code successfully in a simple java project.

    Can any one help me how to get out of this issue.

  18. gotqn says:

    Hi, I am trying to make a sample native method to work but not able till now. I need help to understand what I am doing wrong.

    This is the example I am following : http://netbeans.org/kb/docs/cnd/beginning-jni-linux.html

    The example is for linux, but I am using windows XP ( In the part of including directories I add win32 from java folder, except linux – I hope this is not the problem).

    I do everything from the example good, build without errors, except the last build. It gives me this message:

    run:
    Exception in thread “main” java.lang.UnsatisfiedLinkError: jnidemojava.Main.nativePrint()V
    at jnidemojava.Main.nativePrint(Native Method)
    at jnidemojava.Main.main(Main.java:20)
    Java Result: 1
    BUILD SUCCESSFUL (total time: 0 seconds)

    and this is the code in my main method (done as in the example)

    I am using Netbeans IDE 6.9.1

    Please, every help will be appreciated. I am stuck with this samples, try about ten different samples from the net, and still have not been made one of them working … It is important for me to make one of them working because I am new in JNI and reading something like book about it but in the book everything is done in eclipse and to continue with the reading I have to understand how to make the samples there in NetBeans IDE.

    Thanks in advance.

  19. Kai Witte says:

    Your dll is not in the PATH, or it has been built wrong. Make sure to use the correct options as described in the blog post to build the dll. Analyse your dll with appropriate tools.

    I don’t understand what you are doing with the win32.

  20. gotqn says:

    Because It is a sample for linux, when directories are add, in the sample they are include and linux, but I am using windows XP, so in my java dk there is win32. Could this be a problem?

    Plaase, tell me, what’s the difference between shared object and dll? What is best to be used?

  21. Adil says:

    My Case is same as gotqn case. I am using the example – “http://netbeans.org/kb/docs/cnd/beginning-jni-linux.html”. I reached till the end but stuck with the exception :

    run:
    Exception in thread “main” java.lang.UnsatisfiedLinkError: jnidemojava.Main.nativePrint()V
    at jnidemojava.Main.nativePrint(Native Method)
    at jnidemojava.Main.main(Main.java:22)
    Java Result: 1
    BUILD SUCCESSFUL (total time: 0 seconds)

    Any help is highly appreciated.

  22. Adil says:

    Hey gotqn – I got the Solution.

    Right Click Project Folder – Go to Properties -> Click C Compiler -> Tool Option and edit as follows: gcc-3.exe -Wl,–add-stdcall-alias, if you are using gcc-3.exe as compiler or just gcc.exe. You need to append “-Wl,–add-stdcall-alias” to the Compiler Tool Option and it wroked.

    Then Clean and Build the Project and use the resultant .dll or .so in the Main.java program. Let me know if it helped:

    This resolves the error:
    Exception in thread “main” java.lang.UnsatisfiedLinkError: jnidemojava.Main.nativePrint()V
    at jnidemojava.Main.nativePrint(Native Method)
    at jnidemojava.Main.main(Main.java:22)

  23. Oyoqui says:

    I have the same error and can fix it.

    I make an JNI example and everithing works fine then I add that code (the same code and the same DLL) to my project and it don’t work it send me the same error that yours.

    Then I check that the only modification was that I add the package instruction in my java code. I google it and see that I need to change the name of all my C methods to contain the new path of mi java files. You can use:

    javah -jni MiJavaClass

    and compare the generated .h file with your actual C code and if it is differente change it and create the new DLL and try to access it.

  24. anandhrds says:

    Thanks for all the members in this post….
    If you are using gcc complier, then add “-Wl,-kill-at” as one of the argument to gcc, This will solve the problem.
    So, for example, in my case the command looks like this
    “-Wl,-kill-at” -shared HelloWorld.c “-Ic:\Program Files\Java\jdk1.6.0_02\include” “-Ic:\Program Files\Java\jdk1.6.0_02\include\win32” -o ${workspace_loc:/JNISampleJava/bin}\HelloWorld.dll

  25. Daniel says:

    Idk if this will help anyone, but I’m using C++ compiling with VS win64 2010 command prompt.
    I used the -MD option suggested fix and it did not affect my link problem.
    I since my code was written in C++ I had modified my JNI header file code and removed this code:
    “#ifdef __cplusplus
    extern “C” {
    #endif

    //Method prototypes

    #ifdef __cplusplus
    }
    #endif”
    Obviously I’m not very clever. Once I put this code back in and ran the dumpbin tool (thanks to whoever mentioned that first) I got a perfect looking signatures.
    This solved my linking issue.

  26. Mark M says:

    I have a probable solution for anyone getting this error when working with Eclipse! If you are loading your dll file as a resource into your system classloader, then you absolutely must do a project–>clean every single time you update your dll!! Even restarting eclipse or your computer won’t clear the old dll resource from your classloader. Tracking that one down was incredibly painful!

  27. Hari says:

    Thanks Alexandra,
    Yes, removing the -MD make it work for me! I am sure you know why by now. Could you pl. share it in this forum?

    Regards … Hari

  28. Jigar Thakkar says:

    Alexandra Niculai and degree are correct, deleting the -MD from the command works perfect thank you.

  29. Nice tutorial and thanks for sharing information. I have also share my view as How to fix java.lang.unsatisfiedLinkError in java let me know how do you find it.

  30. Dhiral says:

    thanks a lot
    i generate .dll files using GCC but it’s create problem like
    java.lang.UnsatisfiedLinkError

    But then i used TCC (Tiny C compiler ) and generate .dll and it’s works for me……..

  31. Prahalad Das says:

    All thanks to you, i am able to run my first jni java after 11 years working in java & i used to give up in between and never used to work so hard to look for solution and used to stick with java alone.

    Thanks to you solution
    -Wl,–add-stdcall-alias -mno-cygwin

    It did the all the magic, thanks for this kind blog.

  32. vivek says:

    -Wl, –kill-at OR -Wl,–add-stdcall-alias worked for me

    Thank you SO much for your help kai W

  33. […] fixed the method names in mylib.dll, as suggested here. The method names had somehow gotten mangled by the compiler, but I added linker flags and the dll […]

Leave a Reply

You must be logged in to post a comment.