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.
Related
I'm trying to build a template Android app using Grammatical Framework's Java bindings (however, I don't think what Java code I'm using in particular actually matters. Let's just say I'm trying to use some external non-Android Java code in an Android app).
After some trial and error, I got to successfully build an app using this external code by following these steps:
generating a .jar file for the library I want to use (it's called jpgf.jar
copying it to app/libs
adding it as a library and verifying that the build.gradle gets updated with
implementation files('libs/jpgf.jar')
importing it in my app's MainActivity and writing some code that uses it
However, nothing can be easy in Android development, ever. So my app, after nicely compiling, crashes on startup with the following error:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/bho.harisont.gfdemo-8c870hpW06uEnMQHV1ILjw==/base.apk"],nativeLibraryDirectories=[/data/app/bho.harisont.gfdemo-8c870hpW06uEnMQHV1ILjw==/lib/x86, /system/lib, /system/product/lib]]] couldn't find "libjpgf.so"
In short, some .so file can't be found. Now, I'm not Java or .so file expert, but I do know that when I installed jpgf system-wide on my machine using the dedicated Makefile, a .so file was generated and copied to some location. My probably naive attempt was to take that .so file and move it to the appropriate subfolder of jniLibs. I know I placed it in the correct folder and all, because in this way I managed to change the error message, but not to solve the problem: at this point the complaint is that libjpgf.so is 64 instead of 32 bits. You bet, my machine is 64 bits.
So, to help me you can answer one both of these questions:
how do I compile a 32 bit version of the .so file on a 64 bit machine? I tried some gcc options but it's not like that helped
do I actually need that prebuilt .so file? I see other people just importing JARs. Can I not just do that (or even import the source code somehow), and have Android Studio generate all the assets it wants the way it wants?
I have been trying to use OpenCV with Java without success. I am currently running Linux. I downloaded the OpenCV library from Github, but when I try to run any program, it gives me an error on the line: System.load(Core.NATIVE_LIBRARY_NAME);
The error is "Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: opencv_java400"
I have been told I need to provide a path to a .dll file; however, the current version of OpenCV appears not to contain any .dll files.
Any suggestions would be appreciated, thank you.
The message of the Exception is everything you need. You are supposed to provide an absolute path to the file.
Normally you would put the native libraries as resource in your java package (*.jar). Before loading you must extract the file to a temporary directory of the executing system and then invoke the System.load(..).
As already mentioned a dll typically names a dynamic runtime library on windows os.
I am experiencing a problem in Java (Eclipse) regarding the usage of dlls. Until now, I am experiencing the following problem:
Uncaught Exception for agent SomeAgent
java.lang.UnsatisfiedLinkError: SomePackage.SomeClass.SomeNativeMethod(II)Z
[...]
at jade.core.behaviours.Behaviour.actionWrapper(Behaviour.java:344)
at jade.core.Agent$ActiveLifeCycle.execute(Agent.java:1532)
at jade.core.Agent.run(Agent.java:1471)
at java.lang.Thread.run(Thread.java:745)
I don't know if this will help to figure out the problem, but I am also using JADE in this project...
EDIT (28/04/2014):
The dll which I am trying to use is a custom one (was created by an ex-employee from the company where I work).
The curious thing about this problem is that I have 2 java projects which perform similar tasks. One of this projects runs perfectly, while the other one is experiencing the UnsatisfiedLinkError.
About the paths: I've created a specific folder for the dlls which is contained in the workspace folder, but not inside the project folder (in other words, the same folder where bin, src, bibs, settings, etc. are). This folder's configuration is equal for the both projects I have. Also, I've already tested the System.out.println(System.getProperty("java.library.path") method and the right path is returned on both cases.
EDIT (29/04/2014):
Just added some additional information regarding the error messages. I am starting to think that the problem may be related to the JADE usage...
Here is a PD procedure that might help you identify the problem.
Add the following to your program to identify the differences in the arch and load paths between the two runtime environments. Investigate any differences in path/arch.
System.out.println(System.getProperty("java.library.path"));
System.out.println(System.getProperty("sun.arch.data.model"));
You can use the dumpbin.exe utility to identify the dependencies needed by the DLL that is being loaded.
Make sure the dependencies exist.
Example usage:
C:> dumpbin /imports your.dll
Dump of file your.dll
File Type: DLL
Section contains the following imports:
**KERNEL32.dll**
You can use the where.exe command to find the location of the dependencies.
Example usage:
C:>where KERNEL32.dll
C:\Windows\System32\kernel32.dll
If you see:
C:>where KERNEL32.dll
INFO: Could not find files for the given pattern(s)
Investigate why the dependent DLL is not on the path.
You can use the dumpbin.exe command to check 64bit vs 32bit.
Example:
C:>dumpbin /headers yourd.dll
Dump of file yourd.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (x86) <-- 32bit DLL
C:>dumpbin /headers yourd.dll
Dump of file yourd.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
8664 machine (x64) <-- 64bit DLL
Investigate any 32bit vs 64bit mismatches between main/dependent. If your JVM is 32bit, you need to use 32bit DLLs. If your JVM is 64bit, you need to use 64bit DLLs. ( It is okay to run a 32bit JVM on a 64bit OS but the JNI DLLs must be 32bit ( DLLs match the JVM not the OS ).
Contrary to several answers here, this is not a library loading problem. See the stack trace. It's a problem locating the method named in the exception. This is caused by a mismatch between the actual and expected names. Popular causes:
not using javah to generate the .h file
method signature in .h and .c/.cpp file do not agree
not including the .h file in the .c or .cpp file
changing the package or name of the Java class after running javah
changing the method name or signature after running javah
If you do either of the last two you must re-run javah and adjust the .c/.cpp file to agree with the new signature in the new .h file.
This might be due to version mismatch or bit mismatch of your library. You may be working on 64 bit OS, use 64 bit compatible versions of your JAR files. Also check for version mismatch between JARS.
When you use some native library your system will check it in both environment variable and java.library.path. system property if it does not found there then it will throw java.lang.UnsatisfiedLinkError. Windows pick dll form system32 because system32 folder already exists in the path so there is very less change of error form this side. Native libraries make java code platform dependent. Check your java path for the required dll. Check your java.library.path and try to load your library(without dll extension) by using System.loadLibrary("library name"). Hope this help. :)
This is the directory structure I want to create when I finally deploy my software. It is a Java chat client with a webcam feature and for the webcam I am using LTI-CIVIL.
I was told that I can not use DLLs right from the JAR and I will have to extract them somewhere. All cool. However, what I cannot get my head around is how can I make it work ?
LTI comes with a large number of files in the zip that they provide on their site. If you are using Eclipse, you need to set the path to appropriate folder for the native library. However, this limits me to Eclipse and prevents me from distributing the JAR to my friends. Apparently, I will now have to point to that folder, and maybe load the files, programatiaclly
I am a beginner so if someone can download LTI-CIVIL, have a look at the directory structure and let me know how to achieve what I am trying to do then that would be highly appreciated.
AFAIK, for my 32 bit Windows, I need to point to native/win32-x86 folder.
What I am trying to do is to load the appropriate files in memory so that I can provide webcam facility. I want to avoid installers and simply give a zip file with a directory structure mentioned above so that people can extract, run the jar file from the folder and start chatting.
Clarification: I am trying to send a library with jar file and not in jar. I know extracting and using dlls from jar is tough
I'm assuming that it is not your own code which loads the native libraries (System.load), and they are loaded by a third-party jar (lti-civil).
In this case you have to set the enviroment variable LD_LIBRARY_PATH appropiately before lti-civil attempts to load the native libraries.
Either:
With a launcher script (e.g .bat), set the variable before running java, or set the system property, something like:
java -jar your.jar -Djava.library.path=/path/to/native/folder
At runtime. In the entry point of your program.
This is a bit "hackish", but it works.
Check this link for example:
http://nicklothian.com/blog/2008/11/19/modify-javalibrarypath-at-runtime/
Since you do not know the exact path beforehand, in both cases you will have to also find the correct path where the native libraries are located.
If the path to the libraries is relative to the path of the jar/launcher, then find the current path of the executable:
in a .bat launcher:
Get Directory Path of an executing Batch file
in java:
How to get the path of a running JAR file?
And then that, you can assume the libraries are located in path relative to this (../native), just calculate the path (and maybe expand it to an absolute path).
After you have calculated the absolute path, set the enviroment/system property as described in the first part of the answer.
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)