I had done a cmake on OpenCV linux version and it created all the required shared objects (libraries).
I was even able to call sample OpenCV programs using those libraries, from Java using JNI on my system. It was running.
But when I try to load libhighgui.so.2.0 in the Hadoop Mapper using
System.load("path/to/libhighgui.so.2.0");
I get the error:
UnsatisfiedLinkError:/path/to/libhighgui.so.2.0: libjpeg.so.62: cannot
open shared object file: No such file or directory
Interestingly, CMake on OpenCV did not create this libjpeg.so.
Any help / solution you have?
Thanks in advance..
EDIT: Other libraries are getting loaded successfully and I am using Distributed Cache for distributing the shared libraries.
what does ldd path/to/libhighgui.so.2.0 yield on the command line?
Your shared library depends on other shared libraries, and these shared libraries are not available on the standard library path at runtime.
You'll need to ensure that all the .so's your library depends on are also on the library path for each cluster node (either a standard system path like /lib, or you'll need to amend the java.library.path system property to include a non-standard directory - or just push them using the DistributedCache also, as it add the local folder to the library path)
Related
I'm trying to specify the library load path for JNA on linux for a C++ library.
From the java doc I used -Djna.library.path when calling my program but JNA fails to load the library.
This is how I call the program:
java -jar -Djna.library.path=/home/lib program.jar
When I use -Djna.debug_load=true I can see the library path and JNA trying to find the library, the path is correct and the library name is also correct, but it doesn't load. JNA continues to search the resource path for the library and then fails to find it.
When I put the library in the current directory (same level as program.jar) JNA is happy and the library is loaded without issue.
When I use:
java -cp program.jar:/home/lib package.program
JNA also loads the correct library.
Does anyone here know why -Djna.library.path does not work? Is it because I'm using a jar application file with a manifest?
Anyone with a similar problem?
Please note that once you leave JVM, jna.library.path or java.library.path is no longer taken into account.
Make sure to set LD_LIBRARY_PATH such way it points to locations where libshared.so is located.
Update:
Take a look here to check how using code from shared lib works:
https://github.com/mkowsiak/jnicookbook/blob/master/recipes/recipeNo023
I am trying to run a program which uses JMagick. I have added the native library libJMagick.so as well as libMagick.so.10 (64 bit, matching my system's architecture) to my java.library.path. But when I am trying to run the program I am getting following error:
libJMagick.so: libMagick.so.10: cannot open shared object file: No
such file or directory
From error, it looks like it is finding the libJMagick.so file, but it is not able to find libMagick.so.10, although it is present in java.library.path.
I have ImageMagick installed in my system.
When you copy the .so files, Please do it in respective folders. So that the Java application will load the libraries available for the usage. This is all about your configuration issue. Where to store the shared object files, They should be available on the path.
I am working on a Java project in NetBeans using JNA. According to the JNA documentation, I can make my DLL:s available to Java by putting it in the jar:
Make your native library available on your classpath, under the path {OS}-{ARCH}/{LIBRARY}, where {OS}-{ARCH} is JNA's canonical prefix for native libraries (e.g. win32-x86, linux-amd64, or darwin). If the resource is within a jar file it will be automatically extracted when loaded.
This is what I want to do, so I have included the DLL:s in the project under src/win32-x86-64. If I build a jar-file with netbeans, and then include the jar file in another project everything works fine and JNA finds my library without a problem. This is what I get with jna.debug_load on:
Looking in classpath from sun.misc.Launcher$AppClassLoader#15db9742 for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/C:/MyNetBeansProject/dist/lib/jna-4.2.2.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'MyLibrary'
Adding paths from jna.library.path: null
Trying MyLibrary.dll
Adding system paths: []
Trying MyLibrary.dll
Looking for lib- prefix
Trying libMyLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader#15db9742 for MyLibrary
Found library resource at file:/C:/MyNetBeansProject/build/classes/win32-x86-64/MyLibrary.dll
Looking in C:/MyNetBeansProject/build\classes\win32-x86-64\MyLibrary.dll
Found library 'MyLibrary' at C:/MyNetBeansProject/build\classes\win32-x86-64\MyLibrary.dll
Apparently the DLL from the jar is not used. Instead the DLL from the build folder is used.
Now, if I move the jar-file to another folder and include it in my project, I get a UnsatisfiedLinkError. JNA gives the following output:
Looking in classpath from sun.misc.Launcher$AppClassLoader#70dea4e for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/C:/SomeFolder/lib/jna-4.2.2.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'MyLibrary'
Adding paths from jna.library.path: null
Trying MyLibrary.dll
Adding system paths: []
Trying MyLibrary.dll
Looking for lib- prefix
Trying libMyLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader#70dea4e for MyLibrary
Found library resource at jar:file:/C:/SomeFolder/MyNetBeansProject.jar!/win32-x86-64/MyLibrary.dll
It looks like JNA finds the DLL in the jar, but it does not try to extract it. I can not find it in my temp folder (where JNA extracts it's own internal DLL).
What is the problem here? Why doesn't JNA extract the file? How can I fix this?
(I don't know if this is relevant, but I should mention that my DLL depends on multiple other DLL files that are in the same folder in the jar. Not sure if JNA will extract them automatically for me, but so far it seems JNA isn't even extracting the DLL I am actually using.)
EDIT: There seems to be no problem locating jnidispatch.dll. According to the output when jna.debug_load.jna is set to true the file is found in the JAR and extracted to the temp folder.
JNA show error "UnsatisfiedLinkError" when dll couldn't be loaded. If your DLL needs another custom DLLs not present in the system path it will fail, as JNA doesn't extract this dll automatically.
JNA as a Java library doesn't know the dependencies of the system library, so it can't extract from the jar. The solution is to specify all the dependencies in the JNA Java interfaces.
You can see an example here Load multiple dependent libraries with JNA
What is happening behind the scenes of the Operating System
At the end, the libraries are loaded by the operating system as requested by the main executable. In this case the main executable is java.exe or (jvm.dll). If the system can't find a library in the path it fails and java generates an exception.
Another related and solved question is Registering multiple .dll libraries into a single java class using JNA
The Java application has the JNI module to use.
Where should a user (or an installation script of this application) put the JNI module on Linux (Ubuntu) or on MacOS X so that this JNI module could be loaded without specifying the path to the module in code?
This is a link to a detailed explanation of shared objects and how they are searched for by the OS.
I wish Java people would stop using LD_LIBRARY_PATH and start using the existing directory structures and the ld.so.conf mechanism. Even the OpenJDK libraries are dumped in a place that's not on a standard path and they don't add an ld.so.conf file either ( just how hard is that ? ).
This approach avoids the need to set up your own LD_LIBRARY_PATH and launch via a shell script.
If a required shared object is to be installed, first test for somewhere like /usr/local/lib as an installation choice system wide, and if it exists and an existing file does not already use your file's name, then put your library there. A more systematic approach would be to check all the ld.so.conf files and see if any of the directories match something you know can be used. A shell script can do that at install time.
Put the compiled libraries (.so files on Linux or .dylib on MacOS) into a directory of your choice and include this directory in the library search path LD_LIBRARY_PATH used to start your JVM.
I have a library in eclipse that uses native libraries (two dll). The dlls are in the same folder as the jar. When I run the application there is an error:
java.lang.UnsatisfiedLinkError: no xx in java.library.path
When I link the library by double click on native library location, then running it works. However, I don't want to have to do this, I want it to work with out having to configure it via the IDE. I want the library to be plug and play.
Q1: Where is the convetional location to put .dll referenced by a .jar library.
Q2: How can I make sure when someone references my library in eclipse it works without further IDE configuration?
Error explains it clearly that your native libraries are not in the default location of java.library.path
You just have to set property java.library.path to the folder where all native libraries are stored. You can do this by giving argument in the command line -Djava.library.path=C:/nativeLibs/
OR
Copy your libraries to default location of java.library.path
Refer Default Java library path? for default location of java.library.path