jna : Could not find JNA native support - java

I am using this tutorial to use C in android, but I have an error at this line:
CTest ctest = (CTest) Native.loadLibrary("ctest", CTest.class);
This is the error:
Caused by: java.lang.UnsatisfiedLinkError: Could not find JNA native
support
at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:754)
at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:736)
at com.sun.jna.Native.(Native.java:131)
... 15 more
I put libctest.so in libs folder.
What's the problem?

JNA is trying to load libjnidispatch.o and cannot find it. If not found on the system, JNA attempts to unpack the appropriate library from jna.jar, which is apparently not in your classpath.
EDIT
In the case of android, you have to bundle libjnidispatch.o with your application explicitly. Android will not allow JNA to unpack and load the native library on its own.
See also this answer.

Related

Is there a way to set up dependency for javacv's native part in maven, without manual installation and setting up java.library.path?

I have dependencies on org.bytedeco:opencv:4.1.2-1.5.2 that is in turn added to the project by
<groupId>org.datavec</groupId>
<artifactId>datavec-data-image</artifactId>
<version>${datavec.version}</version>
And for the needs of datavec-data-image the open-cv is loaded well and all the internal open-cv actions are executed.
Then, I'd like to do some open cv executions explicitly. I use a class from https://github.com/rostrovsky/pdf-table that does this stuff:
public class PdfTableReader {
private TableExtractor extractor;
private PdfTableSettings settings;
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
and it fails with
Exception in thread "main" java.lang.UnsatisfiedLinkError: no opencv_java412 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at pdftable.PdfTableReader.<clinit>(PdfTableReader.java:32)
at pdftable.ExtractSyzlekFromPdf.main(ExtractSyzlekFromPdf.java:12)
What I should to do to make this explicit javacv part to work with datavec image code without doing the double explicit open-cv installation to some location on my pc and setting up the java.library.path explicitly? At least the datavec image code obtains it somehow without this explicit set up.
I also tried to follow up this answer: https://stackoverflow.com/a/57515132/1759063 but with no success (if I understand right, they use the dependency that ships native libs in a cross-platform way, i.e. ships all platform binaries and the needed one is used on the right platform). I suppose there should be a way to make java.library.path to be dynamically updated if the open-cv native binaries packed to the maven dependencies are attached to the project. But how?
If DL4J guys can explain how to use the javacv part there correctly, that would be perfect.
The Java API of OpenCV found in the org.opencv package doesn't come with a loader, so the libraries need to be loaded by something else externally. In the case of the JavaCPP Presets for OpenCV, the libraries and wrappers are all bundled in JAR files and we can call Loader.load(opencv_java.class) to load everything as documented here:
https://github.com/bytedeco/javacpp-presets/tree/master/opencv#documentation
JavaCV, Deeplearning4j, and DataVec do not use that Java API of OpenCV, they use the API found in the org.bytedeco.opencv package, which loads everything automatically, so they do not need to call anything.

System.loadLibrary loads something else

In my java code, I call System.loadLibrary(A); to load the A.so library. However, my app crashes at run time with this error:
java.lang.UnsatisfiedLinkError: dlopen failed: library "B.so" not found
Admittedly, the B.so library is a dependency of A.so library. But I did not explicitly call System.loadLibrary() on B.so anywhere. I was under the impression that B.so will be covered by A.so. Why is the Java runtime trying to load B.so?
Thanks!

Can't load personal dll with jna from netbeans

I'm using netbeans 7.4 / jdk 1.7u51
I downloaded the jar for JNA from official site, in version 4.0.0.
I have an internally developped DLL whose interface is in plain C, which loads perfectly well with ctypes in python. This dll is compiled in release with visual 2010, whose runtime are in path.
D:\fl006\Downloads>dir D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Directory of D:\deploy\SpotLight\spotlight-1488
29.01.2014 11:13 1'690'112 PasanBusLibrary.dll
I tried to load it in java with jna:
public interface CLibrary extends Library {
(...snip...)
void pasanIpcInitializeLibrary(String xClient, String xBusName, int xTimeout);
void pasanIpcTerminateLibrary();
}
public static void main(String[] args) {
NativeLibrary.addSearchPath("PasanBusLibrary","D:\\deploy\\SpotLight\\spotlight-1488");
CLibrary Bus = (CLibrary) Native.loadLibrary("PasanBusLibrary",CLibrary.class);
(... snip ...)
This is basically an out of the book standard dll load, from a custom location.
When activating jna debug, I see the following :
run:
Looking in classpath from sun.misc.Launcher$AppClassLoader#714a8f44 for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/D:/code/perso/TestWrapperBus/jna-4.0.0.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'PasanBusLibrary'
Adding paths from jna.library.path: null
Trying D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Adding system paths: []
Trying D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Looking for lib- prefix
Trying libPasanBusLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader#714a8f44 for PasanBusLibrary
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'PasanBusLibrary': Native library (win32-x86-64/PasanBusLibrary.dll) not found in resource path ([file:/D:/code/perso/TestWrapperBus/jna-4.0.0.jar, file:/D:/code/perso/TestWrapperBus/jna-platform-4.0.0.jar, file:/D:/code/perso/TestWrapperBus/build/classes/])
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:271)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Library$Handler.<init>(Library.java:147)
at com.sun.jna.Native.loadLibrary(Native.java:412)
at com.sun.jna.Native.loadLibrary(Native.java:391)
at testwrapperbus.TestWrapperBus.main(TestWrapperBus.java:39)
It looks it looks through the location I gave and somehow discards it. I tried different folders and I got same behaviour, there is no obvious file system right issue (dll is RW from all users)
Any clue on what I'm missing, I'm kind of stuck currently...
EDIT
if I load "msvcrt" this is working nice to cll printf
my dll has some dependencies, all of them hosted in c:\windows\system32 (standard runtime, dynamically linked)
My dll is a win32 compilation while I use a win64 JDK / JRE. Of course, when dealing with pure java, we don't care but loading native library needs to match.
I tried running from command line on a 32 bits JRE7 and it worked, so I'm pretty sure that installing JDK for win32 in my netbeans or recompiling my dll in 64 bits will solve the issue.
Thanks to this answer : Trying to use DLL from Java (JNA). Unable to load library exception for having put me on the righteous path

Mac + jni + java

A little background:
I have a java application that needs to talk to a third party hardware on mac. They have given me the sdk but it is not in Java. So I am trying to make jnilib that will act as a bridge between my java application and the SDK.
The issue:
I have made a small sample jnilib that talks to the SDK but when I try to use it in my java program I get the following error
Exception in thread "main" java.lang.UnsatisfiedLinkError: /Users/john.doe/Desktop/eclipse/workspace/Lesson13_Jni_Smart7/bin/libSmartTest7.jnilib: Library not loaded: build/Release/SMARTResponseSDK.framework/Versions/A/SMARTResponseSDK Referenced from: /Users/john.doe/Desktop/eclipse/workspace/Lesson13_Jni_Smart7/bin/libSmartTest7.jnilib
Reason: image not found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1827)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1742)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1045)
at com.learning.lesson13.JniSmart7.<clinit>(JniSmart7.java:6)
From the error it looks like my libSmartTest7.jnilib is looking for the library SMARTResponseSDK.
What I have tried
I know where the library SMARTResponseSDK is on my Mac. I tried copying it over to my working folder in eclipse but I still get the error. I have tried using the -DJava.library.path but I still get the error.
Any ideas on what the best possible approach would be.
Once you are inside JNI code, it no longer matters what java.library.path points at.
Once you are inside JNI code, all you can do is to make sure library is visible to your code via LD_LIBRARY_PATH/DYLD_LIBRARY_PATH, or you can dynamically load your library file from any location you like.
So, for you, I suggest to take a look here:
dynamic loading of library in JNI - http://jnicookbook.owsiak.org/recipe-No-018/
Calling code from shared library (adapter pattern) - http://jnicookbook.owsiak.org/recipe-No-023/
You can also benefit from compilation flags while building your JNI library and use rpath.

What is the cause of an UnsatisfiedLinkError?

When i am trying to run my program it is giving the following error
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jacob-1.14.3-x86 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1030)
at com.jacob.com.LibraryLoader.loadJacobLibrary(LibraryLoader.java:184)
at com.jacob.com.JacobObject.<clinit>(JacobObject.java:108)
at javaSMSTest.main(javaSMSTest.java:18)
please help
From the Javadoc:
Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native.
It is an error related to JNI. loadJacobLibrary is trying to load the native library called jacob-1.14.3-x86 and it is not found on the path defined by java.library.path. This path should be defined as a system property when you start the JVM. e.g.
-Djava.library.path=<dir where jacob library is>
On Windows, the actual native library file will be called jacob-1.14.3-x86.dll while on Linux it would be called libjacob-1.14.3-x86.so
You need the jacob-1.14.3-x86 library on your java library path.
On windows, this would be jacob-1.14.3-x86.dll.
This is a binary file which is used by java to run native methods. It's probably required by some library (jar) you're using.
In here you can see not only a jar, but also the binary required by the jar. Pick the one for your platform.
To quote http://www.velocityreviews.com/forums/t143642-jni-unsatisfied-link-error-but-the-method-name-is-correct.html:
There are two things that cause UnsatisfiedLinkError. One is when
System.loadLibrary() fails to load the library, the other is when the
JVM fails to find a specific method in the library. The text of the
error message itself will indicate which is the case...
The error which you describe clearly cannot find the library at all. As the others have said, include it in your Java library path.
The other error—when the library can be found but the method within the library is not found—looks as follows:
java.lang.UnsatisfiedLinkError: myObject.method([Ljava/lang/Object;)V
In this case you either have the wrong method name, or will have to go back and add the method and recompile the code...

Categories

Resources