java.lang.UnsatisfiedLinkError: no jzmq in java.library.path - java

I have a java application using an external dll (zmq). When I run it in debug mode in Eclipse it's all fine. However, when I export the application as Runnable JAR file then trying to run it, I'm getting that error referencing the dll.
Following my research on this site I configured the build path for JRE System Library, added that path of the folder containing the dll to Native library location, but I'm still getting that error.
Is there anything I need to do further? Or different?
Thanks.

JZMQ needs two things to run: zmq.dll (the native ZMQ library) and jzmq.dll (the "bridge" library between Java and ZMQ). The particular error you are getting means your compile environment can't locate jzmq.dll; you just need to specify the path where it can find jzmq.dll. Note that, as far as I'm aware, there is no way for jzmq.dll to be in a JAR file so you can just include it in your classpath.
Unfortunately, I can't tell you exactly how to do it in Windows. I come from Linux, where DLLs are SO files. There it would be a simple export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/jzmq.

Related

MCP 1.8.9 Exception in thread "main" java.lang.UnsatisfiedLinkError: no lwjgl64 in java.library.path [duplicate]

I'm working on a Java project that uses the JNI. The JNI calls a custom library that I've written myself, let's say mylib.dll, and that depends on a 3rd party library, libsndfile-1.dll.
When I run my program it crashes with
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
I've searched this site (and others) and I've tried a number of fixes:
I ran dependency walker. DW gave a couple of warnings -- that two libraries required by libsndfile, MPR.DLL and SHLWAPI.DLL, had "unresolved imports" -- but the DW FAQ said that these warnings could be safely ignored.
I 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 method names now match those in my jni header file exactly.
I put all of these DLLs in the same directory -- the same directory as the .jar that calls them -- to ensure that they're on the right PATH.
No dice.
Does anyone have any idea what's going on?
I'm doing my development in Visual Studio 2010 on a MacBook pro (via Parallels). I'm doing my testing in Windows XP on a toshiba laptop.
I'm pretty sure the classpath and the shared library search path have little to do with each other. According to The JNI Book (which admittedly is old), on Windows if you do not use the java.library.path system property, the DLL needs to be in the current working directory or in a directory listed in the Windows PATH environment variable.
Update:
Looks like Oracle has removed the PDF from its website. I've updated the link above to point to an instance of the PDF living at University of Texas - Arlington.
Also, you can also read Oracle's HTML version of the JNI Specification. That lives in the Java 8 section of the Java website and so hopefully will be around for a while.
Update 2:
At least in Java 8 (I haven't checked earlier versions) you can do:
java -XshowSettings:properties -version
to find the shared library search path. Look for the value of the java.library.path property in that output.
I want to inform this interesting case, after tried all the above method, the error is still there. The weird thing is it works on a Windows 7 computer, but on Windows XP it is not. Then I use dependency walker and found on the Windows XP there is no VC++ Runtime as my dll requirement. After installing VC++ Runtime package here it works like a charm. The thing that disturbed me is it keeps telling Can't find dependent libraries, while intuitively the JNI dependent dll is there, however it finally turns out the JNI dependent dll requires another dependent dl. I hope this helps.
You need to load your JNI library.
System.loadLibrary loads the DLL from the JVM path (JDK bin path).
If you want to load an explicit file with a path, use System.load()
See also: Difference between System.load() and System.loadLibrary in Java
If you load a 32 bit version of your dll with a 64 bit JRE you could have this issue. This was my case.
Please verify your library path is right or not. Of course, you can use following code to check your library path path:
System.out.println(System.getProperty("java.library.path"));
You can appoint the java.library.path when launching a Java application:
java -Djava.library.path=path ...
Did have identical problem with on XP machine when installing javacv and opencv in combination with Eclipse. It turned out that I was missing the following files:
msvcp100.dll
msvcr100.dll
Once these were installed, the project compiled and ran OK.
When calling System.loadLibrary(), the JVM will look on the java.library.path for your native library. However, if that native library declares any dependencies on other native libraries, then the operating system will be tasked with finding those native library dependencies.
Since the operating system has no concept of the java.library.path, it will not see any directories you place on the java.library.path. Instead, it will only search the directories on PATH environment variable of the operating system. This is totally fine if the native library dependency is an operating system native library because it will be found on the PATH. However, if the native library dependency is a native library that you or someone else created, then it will not be found on the PATH unless you place it there. This behavior is strange, unexpected, and not well documented, but it is documented in the OpenJDK issue tracker here. You can also find another StackOverflow answer reinforcing this explanation, here.
So, you have a couple of options. You could either load each native library in the correct dependency order using System.loadLibrary(), or you could modify the PATH to include the directories where your native libraries are stored.
Short answer: for "can't find dependent library" error, check your $PATH (corresponds to bullet point #3 below)
Long answer:
Pure java world: jvm uses "Classpath" to find class files
JNI world (java/native boundary): jvm uses "java.library.path" (which defaults to $PATH) to find dlls
pure native world: native code uses $PATH to load other dlls
I found a great article by some friends at keepsafe that went through the same thing I did. It worked for me, so hopefully it helps you out as well! Have a read if you're interested (The Perils of Loading Native Libraries on Android) or just use
compile 'com.getkeepsafe.relinker:relinker:1.2.3'
and replace
System.loadLibrary("myLibrary");
with
ReLinker.loadLibrary(context, "mylibrary");
installing Microsoft Visual C++ 2010 SP1 Redistributable Fixed it
I used to have exactly the same problem, and finally it was solved.
I put all the dependent DLLs into the same folder where mylib.dll was stored and make sure the JAVA Compiler could find it (if there is no mylib.dll in the compilation path, there would be an error reporting this during compiling). The important thing you need to notice is you must make sure all the dependent libs are of the same version with mylib.dll, for example if your mylib.dll is release version then you should also put the release version of all its dependent libs there.
Hope this could help others who have encountered the same problem.
I had the same issue, and I tried everything what is posted here to fix it but none worked for me.
In my case I'm using Cygwin to compile the dll. It seems that JVM tries to find the JRE DLLs in the virtual Cygwin path.
I added the the Cygwin's virtual directory path to JRE's DLLs and it works now.
I did something like:
SET PATH="/cygdrive/c/Program Files/Java/jdk1.8.0_45";%PATH%
In my situation, I was trying to run a java web service in Tomcat 7 via a connector in Eclipse. The app ran well when I deployed the war file to an instance of Tomcat 7 on my laptop. The app requires a jdbc type 2 driver for "IBM DB2 9.5". For some odd reason the connector in Eclispe could not see or use the paths in the IBM DB2 environment variables, to reach the dll files installed on my laptop as the jcc client. The error message either stated that it failed to find the db2jcct2 dll file or it failed to find the dependent libraries for that dll file. Ultimately, I deleted the connector and rebuilt it. Then it worked properly. I'm adding this solution here as documentation, because I failed to find this specific solution anywhere else.
Creating static library worked for me, compiling using g++ -static. It bundles the dependent libraries along with the build.
place the required dlls in folder and set the folder path in PATH environment variable.
make sure updated environment PATH variable is reflected.
I was facing same issue with ffmpeg library after merging two Android projects as one project.
Actually issue was arriving due to two different versions of ffmpeg library but they were loaded with same names in memory. One library was placed in JNiLibs while other was inside another library used as module. I was not able to modify the code of module as it was readonly so I renamed the one used in my own code to ffmpegCamera and loaded it in memory with same name.
System.loadLibrary("ffmpegCamera");
This resolved the issue and now both versions of libraries are loading well as separate name and process id in memory.
I faced the same problem after migrating my CI into a new machine.
I was still facing it even after applying all the above solutions.
The problem was in my new machine, there was Microsoft Visual C++ 2010 SP1 Redistributable x86 installed in it. But my new machine was having 64-bit CPU and operating system. So the fix was that i just updated and installed the 64 bit version from here .
Go to http://tess4j.sourceforge.net/usage.html and click on Visual C++ Redistributable for VS2012
Download it and run VSU_4\vcredist_x64.exe or VSU_4\vcredist_x84.exe depending upon your system configuration
Put your dll files inside the lib folder, along with your other libraries (eg \lib\win32-x86\your dll files).

Struts2 and PI4J [duplicate]

I'm working on a Java project that uses the JNI. The JNI calls a custom library that I've written myself, let's say mylib.dll, and that depends on a 3rd party library, libsndfile-1.dll.
When I run my program it crashes with
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
I've searched this site (and others) and I've tried a number of fixes:
I ran dependency walker. DW gave a couple of warnings -- that two libraries required by libsndfile, MPR.DLL and SHLWAPI.DLL, had "unresolved imports" -- but the DW FAQ said that these warnings could be safely ignored.
I 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 method names now match those in my jni header file exactly.
I put all of these DLLs in the same directory -- the same directory as the .jar that calls them -- to ensure that they're on the right PATH.
No dice.
Does anyone have any idea what's going on?
I'm doing my development in Visual Studio 2010 on a MacBook pro (via Parallels). I'm doing my testing in Windows XP on a toshiba laptop.
I'm pretty sure the classpath and the shared library search path have little to do with each other. According to The JNI Book (which admittedly is old), on Windows if you do not use the java.library.path system property, the DLL needs to be in the current working directory or in a directory listed in the Windows PATH environment variable.
Update:
Looks like Oracle has removed the PDF from its website. I've updated the link above to point to an instance of the PDF living at University of Texas - Arlington.
Also, you can also read Oracle's HTML version of the JNI Specification. That lives in the Java 8 section of the Java website and so hopefully will be around for a while.
Update 2:
At least in Java 8 (I haven't checked earlier versions) you can do:
java -XshowSettings:properties -version
to find the shared library search path. Look for the value of the java.library.path property in that output.
I want to inform this interesting case, after tried all the above method, the error is still there. The weird thing is it works on a Windows 7 computer, but on Windows XP it is not. Then I use dependency walker and found on the Windows XP there is no VC++ Runtime as my dll requirement. After installing VC++ Runtime package here it works like a charm. The thing that disturbed me is it keeps telling Can't find dependent libraries, while intuitively the JNI dependent dll is there, however it finally turns out the JNI dependent dll requires another dependent dl. I hope this helps.
You need to load your JNI library.
System.loadLibrary loads the DLL from the JVM path (JDK bin path).
If you want to load an explicit file with a path, use System.load()
See also: Difference between System.load() and System.loadLibrary in Java
If you load a 32 bit version of your dll with a 64 bit JRE you could have this issue. This was my case.
Please verify your library path is right or not. Of course, you can use following code to check your library path path:
System.out.println(System.getProperty("java.library.path"));
You can appoint the java.library.path when launching a Java application:
java -Djava.library.path=path ...
Did have identical problem with on XP machine when installing javacv and opencv in combination with Eclipse. It turned out that I was missing the following files:
msvcp100.dll
msvcr100.dll
Once these were installed, the project compiled and ran OK.
When calling System.loadLibrary(), the JVM will look on the java.library.path for your native library. However, if that native library declares any dependencies on other native libraries, then the operating system will be tasked with finding those native library dependencies.
Since the operating system has no concept of the java.library.path, it will not see any directories you place on the java.library.path. Instead, it will only search the directories on PATH environment variable of the operating system. This is totally fine if the native library dependency is an operating system native library because it will be found on the PATH. However, if the native library dependency is a native library that you or someone else created, then it will not be found on the PATH unless you place it there. This behavior is strange, unexpected, and not well documented, but it is documented in the OpenJDK issue tracker here. You can also find another StackOverflow answer reinforcing this explanation, here.
So, you have a couple of options. You could either load each native library in the correct dependency order using System.loadLibrary(), or you could modify the PATH to include the directories where your native libraries are stored.
Short answer: for "can't find dependent library" error, check your $PATH (corresponds to bullet point #3 below)
Long answer:
Pure java world: jvm uses "Classpath" to find class files
JNI world (java/native boundary): jvm uses "java.library.path" (which defaults to $PATH) to find dlls
pure native world: native code uses $PATH to load other dlls
I found a great article by some friends at keepsafe that went through the same thing I did. It worked for me, so hopefully it helps you out as well! Have a read if you're interested (The Perils of Loading Native Libraries on Android) or just use
compile 'com.getkeepsafe.relinker:relinker:1.2.3'
and replace
System.loadLibrary("myLibrary");
with
ReLinker.loadLibrary(context, "mylibrary");
installing Microsoft Visual C++ 2010 SP1 Redistributable Fixed it
I used to have exactly the same problem, and finally it was solved.
I put all the dependent DLLs into the same folder where mylib.dll was stored and make sure the JAVA Compiler could find it (if there is no mylib.dll in the compilation path, there would be an error reporting this during compiling). The important thing you need to notice is you must make sure all the dependent libs are of the same version with mylib.dll, for example if your mylib.dll is release version then you should also put the release version of all its dependent libs there.
Hope this could help others who have encountered the same problem.
I had the same issue, and I tried everything what is posted here to fix it but none worked for me.
In my case I'm using Cygwin to compile the dll. It seems that JVM tries to find the JRE DLLs in the virtual Cygwin path.
I added the the Cygwin's virtual directory path to JRE's DLLs and it works now.
I did something like:
SET PATH="/cygdrive/c/Program Files/Java/jdk1.8.0_45";%PATH%
In my situation, I was trying to run a java web service in Tomcat 7 via a connector in Eclipse. The app ran well when I deployed the war file to an instance of Tomcat 7 on my laptop. The app requires a jdbc type 2 driver for "IBM DB2 9.5". For some odd reason the connector in Eclispe could not see or use the paths in the IBM DB2 environment variables, to reach the dll files installed on my laptop as the jcc client. The error message either stated that it failed to find the db2jcct2 dll file or it failed to find the dependent libraries for that dll file. Ultimately, I deleted the connector and rebuilt it. Then it worked properly. I'm adding this solution here as documentation, because I failed to find this specific solution anywhere else.
Creating static library worked for me, compiling using g++ -static. It bundles the dependent libraries along with the build.
place the required dlls in folder and set the folder path in PATH environment variable.
make sure updated environment PATH variable is reflected.
I was facing same issue with ffmpeg library after merging two Android projects as one project.
Actually issue was arriving due to two different versions of ffmpeg library but they were loaded with same names in memory. One library was placed in JNiLibs while other was inside another library used as module. I was not able to modify the code of module as it was readonly so I renamed the one used in my own code to ffmpegCamera and loaded it in memory with same name.
System.loadLibrary("ffmpegCamera");
This resolved the issue and now both versions of libraries are loading well as separate name and process id in memory.
I faced the same problem after migrating my CI into a new machine.
I was still facing it even after applying all the above solutions.
The problem was in my new machine, there was Microsoft Visual C++ 2010 SP1 Redistributable x86 installed in it. But my new machine was having 64-bit CPU and operating system. So the fix was that i just updated and installed the 64 bit version from here .
Go to http://tess4j.sourceforge.net/usage.html and click on Visual C++ Redistributable for VS2012
Download it and run VSU_4\vcredist_x64.exe or VSU_4\vcredist_x84.exe depending upon your system configuration
Put your dll files inside the lib folder, along with your other libraries (eg \lib\win32-x86\your dll files).

Load native libraries in an Eclipse RCP application on Linux

I have an Eclipse RCP application that uses some native libraries via JNI. These are shared libraries that dynamically link to each other. On Windows I put these libraries (as *.dll files) next to the RCP launcher executable (*.exe) file and load them via System.load("<absolute file path>"). This works great, as the location of the launcher seems to be added to the java.library.path so that dynamic linking between the libraries works.
On Linux, I get an UnsatisfiedLinkError. The location of the launcher is not added to the java.library.path. When I start the application from the terminal after setting the LD_LIBRARY_PATH variable it works:
export LD_LIBRARY_PATH=.
./myApp
The location . is the added to the java.library.path. Is there a better way to do this? I want the users to just double click the launcher.
Setting -Djava.library.path=. in the myApp.ini file does also not work. I see it in the installation details but I still get an UnsatisfiedLinkError.
The most reliable way to find libraries is not using java.library.path at all but finding them via Java code and load via System.load() instead of System.loadLibrary(). You can apply whatever logic you want for finding the native library (although it's probably best trying not to be too clever) and you could fall back to trying java.library.path if your mechanism fails.
This will only work of course if the library doesn't depend on other libraries that might not be found.

java doesn't recognize so libraries

I'm trying to develop a BitTorrent client using the frostwire jlibtorrent librari, but when I run the program alwais obtain the error on the image.
How I can compile using the linux version of the library.
Hi do you run on linux or windows or Mac? The exception indicates that a binary lib can be loaded or found. (the .so file as you indicate).
There is a case the native lib included in the jar - is not compatible or has missing dependencies (links) on your host OS. See here.
The .so library has to be loaded first before it can be used. Use System.load() to do so. Here is an example:
https://www.chilkatsoft.com/java-loadLibrary-Linux.asp

How Do I Install a Jar?

I was reading some documentation for db2jcc4.jar when something caught my attention in the following (emphasis added):
The following command will retrieve the JCC driver version if executed from the command line:
java com.ibm.db2.jcc.DB2Jcc -version
Or for drivers that are not yet installed:
java -cp ./db2jcc.jar com.ibm.db2.jcc.DB2Jcc -version
All I have is the db2jcc4.jar file - it didn't come with an installer or anything. I can run the second command and it works fine, but the first gives me this stack trace:
Exception in thread "main" java.lang.NoClassDefFoundError: com.ibm.db2.jcc.DB2Jcc
Caused by: java.lang.ClassNotFoundException: com.ibm.db2.jcc.DB2Jcc
at java.net.URLClassLoader.findClass(URLClassLoader.java:434)
at java.lang.ClassLoader.loadClassHelper(ClassLoader.java:665)
at java.lang.ClassLoader.loadClass(ClassLoader.java:644)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:358)
at java.lang.ClassLoader.loadClass(ClassLoader.java:627)
Could not find the main class: com.ibm.db2.jcc.DB2Jcc. Program will exit.
This tells me that the jar is not yet installed. In all the time I've worked with Java, I've never heard of installing a jar. How can I make it so that the first command works instead of having this issue and printing a stack trace? How can I install a jar?
It looks to me like the second command includes a flag, -cp, which modifies the classpath. I'm guessing that means that all I need to do is move my jar file into a specific directory. I tried putting it in /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.33.x86_64/jre/lib but that didn't make it so the second command would work. I'm stumped and would appreciate any suggestions for where exactly I need to move this jar for it to be considered installed.
There is no such thing as "installing" a jar. To be used by a Java application, jars have to be accessible in the classpath. Take a look at this link:
http://docs.oracle.com/javase/tutorial/essential/environment/paths.html
By installing the java jar they meant that the jar is available to your program (physically present and found in your class path). If the Path to the jar was not setup then you have to options:
+ copy the jar file to your existing path
+ include the jar file in the command line
java -cp <path_to>/db2jcc.jar com.ibm.db2.jcc.DB2Jcc -version
It looks to me like the second command includes a flag, -cp, which modifies the classpath. I'm guessing that means that all I need to do is move my jar file into a specific directory.
I would say that you need to explicitly include the jar file itself on the classpath. Personally, I generally do not attempt to "install" a jar as you describe, but rather create some sort of script or executable jar file that will facilitate the establishment of the correct classpath.
EDIT: In the context of deploying code to an application server, then "installing" the jar would make sense--typically there's a shared lib folder available on an application server where you can simply drop the jar and the code will become available to all the applications running on the server--this can become a bit of a management headache, however and I often will prefer to have a completely self-contained deployment over sharing jar files between applications--YMMV, however.
You commented thus:
Your link has this comment - (Classes that are part of the JRE, JDK platform, and extensions should be defined through other means, such as the bootstrap class path or the extensions directory.) - How would I go about adding the jar through that?
That is a bad idea, for (at least) the following reasons:
Putting stuff into the extensions directory is going to potentially affect every Java application that you execute. Not just the application that you are trying to "install". In some cases, this may to lead to unexpected breakages due to conflicting versions, etcetera.
When you update the Java installation, the standard installer, RPM or whatever is going to create a new installation tree. But it won't copy anything from the existing installation. So a Java update is likely to break any application that depends on stuff in "extensions".
If you try to solve the above problems by "embedding" a Java installation, you risk losing track of where your Java installations are. This makes applying Java security patches problematic. And of course, embedded JREs take up a lot of disc space ... at ~100Mb a time.
I suspect that "Installing a JAR" is a poorly chosen terminology that likely means placing the jar on the JVM classpath" - i.e. in order to make it available to an application. The recommended ways of doing so vary depending on the Java platform (whether it is a server platform or a client side platform).
For example, on a Java EE server, you could package the jar file within the application, or define it as a shared library, and attach it to the server's classloader or the application's classloader to make it available to that application. Third party applications, such as various IBM products, will come with their own instructions as to how to 'install' a db2jcc4 driver.

Categories