Search code examples
javaeclipsedlljava-native-interfacedllimport

java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()L


I can't run methods of a library. My library is in my PATH and also getting loaded without errors by following code:

    System.loadLibrary("FTDIInterface");

But the functions are not working. I get the following exception:

Caused by: java.lang.UnsatisfiedLinkError: Messgeraet.src.net.sf.yad2xx.FTDIInterface.getDevices()[LMessgeraet/src/net/sf/yad2xx/Device;
at Messgeraet.src.net.sf.yad2xx.FTDIInterface.getDevices(Native Method)
at Messgeraet.src.Emu.EmuConnection.<init>(EmuConnection.java:22)
at Messgeraet.src.Emu.EmuModel.connect(EmuModel.java:27)
at Messgeraet.src.JavaFX.FXController.connect(FXController.java:112)
... 62 more

I am using eclipse. In IntelliJ it is working fine and I also got another eclipse project that includes the library without any problems.

Why it can't run my method FTDIInterface.getDevices?


Solution

  • Your package seems off; Messgereat.src sounds like you have a project dir named Messgereat, within you have a folder named 'src' with your java sources, and you've misconfigured your build tooling; the right package name sounds like it should be: package net.sf.yad2xx;, but due to a misconfigured build it wasn't working and you decided to fix the problem by updating your package statements, but that broke your JNI bindings.

    The solution would then be to undo all the changes you've made to your package statements, and fix your build script instead.

    Alternatively, if you really do intend to use that bizarre package, then make sure you have executed javah with the exact same build setup and use that as a basis for your JNI code. If you've done that, include the exported symbols in the library as the comment by @user2543253 suggested.

    NB: It's a bit odd that your loadLibrary call works at all; PATH has nothing to do with it, but presuambly then your library so happens to be located in a place that is listed on your librarypath, which is the system property (of the VM, not of your OS) named 'java.library.path'; you set it with e.g.:

    java -Djava.library.path=/path1:/path2 -cp /path/to/dep1.jar:/path/to/dep2.jar com.foo.Main
    

    because of this confusion it is also possible that some different native lib file also named FTDIInterface is being loaded instead of the one you think is being loaded. If you want to be certain of what is being loaded, run System.load("/absolute/path/to/the/dll-jnilib-or-so-libraryfile.so"); - then you know for sure.