We've got a GWT web app that uses JNI to call a dll. We build the dll as well. It works fine on my developer machine, which is a 64-bit Windows 7 machine, running Java 6 and running the webapps in Tomcat 6. But when we run it on the tester's VM which is running 32-bit WinXP, it errors with
java.lang.UnsatisfiedLinkError: Cannot load native JNIWrapper library (jniwrap64.dll)
at com.jniwrapper.Library.loadNativeCode(SourceFile:78)
at com.jniwrapper.Library.loadNativeCode(SourceFile:103)
at com.jniwrapper.Library.ensureNativeCode(SourceFile:113)
at com.jniwrapper.Library.load(SourceFile:189)
My JRE_HOME is set to a 32-bit version of Java 6, because I wanted the build to be able to work on a 32-bit machine, but clearly I'm mis-understanding something about how the 32 or 64-bit versions of java work in compiling the web app.
And yes, the dll that we call is built in to the .war, since it works on my machine.
I also googled the jniwrap64.dll but didn't find much that was relevant.
Added for clarification : jniwrap64.dll is not the dll that I've built, and my code is not explicitly loading this library. That's part of my confusion, is what is this library, why is it being loaded, etc. I have assumed that jniwrap64.dll is some kind of system library that needs to be installed. My code that loads our library is as follows:
Library myLib = Library(path);
myLib.load(this.getClass().getClassLoader());
When you load the dll with System.loadLibrary() do you load "jniwrap64.dll" or "jniwrap32.dll" ? Cna you show us the line of code which loads this library?
Related
I have a Java app using a C file via JNI dependant on a C library (FFMPEG). I have compiled two versions of these C libraries and by checking with the Dependency Walker the output is indeed 32 and 64 bit.
I have no problem building and running the 64 bit app with Eclipse 64 bits, 64 bit JRE, compiling my JNI C class with Mingw64. I am trying to do the same on the 32-bit Eclipse with 32-bit JRE and having some issues on System.loadLibrary().
ERROR: java.lang.UnsatisfiedLinkError: C:\Dev\wks\HelloFfmpeg\VideoProcessor\bin\helloffmpeg.dll: Can't find dependent libraries
Here are the checks I have done
Eclipse is 32-bit
In this instance of Eclipse I have only 1 JRE setup, the 32-bit one, and this is the one used to start the app in my Run Configuration
In C/C++ build I have set MINGW_HOME to point to Mingw32 which has 32-bit gcc
I have copied all the required DLLs (the 32-bit version of each and everyone that i use to run the 64-bit version of the app) in the same folder as the helloffmpeg.dll in the BIN folder
Dependency Walker tells me this:
C:\Dev\wks\HelloFfmpeg\VideoProcessor\bin\helloffmpeg.dll is a 32-bit DLL
The 32-bit ffmpeg DLLs I use are indeed 32-bit and found when loading helloffmpeg.dll
Now there are two things that I am not too sure about:
When I build the 32-bit version I get this in Eclipse CDT output, the rest looks fine
Info: Configuration "Default" uses tool-chain "MinGW GCC" that is unsupported on this system, attempting to build anyway.
In Dependency Walker, some system DLLs found are 64-bit version, for example
I am not sure about these they seem to be system libraries, and one is MinGW library. If I distribute my 32-bit app do I need to include some MinGW dlls? This doesn't seem right.
Out of the four errors at the bottom the ones that don't show up with the 64-bit version are these two
Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
Error: Modules with different CPU types were found.
I understand the second as per above but I am not sure to understand the first one.
UPDATE
I followed the advice below and opened the 32-bit DLL with 32-bit dependency walker, and making sure my PATH now points to mingw32/bin and not mingw64/bin. The result is much cleaner and the correct version of LIBWINPTHREAD-1 can be found:
There is no other error when using DWW. However when I start my program I still get
ERROR: java.lang.UnsatisfiedLinkError: [blabla].dll: Can't find dependent libraries
Is there any way to check on which dependent library the JNI loader fails?
UPDATE2
I resolved the problem in update1, I also had a PATH override in my eclipse launch configuration...
I can now successfully start the program and load the JNI library and its dependency. However I still have one issue with the 32-bit library, I get an UnsatisfiedLinkError when trying to call the first JNI method, saying that it doesn't exist. I noticed in DWW that the method names have #8 or #16 after them, I reckon this is causing the problem as the 64-bit DLL doesn't have this
32-bit DLL:
64-bit DLL:
UPDATE 3
The # sign at the end of 32-bit methods is resolved using the answer from kool on this thread.
I have a very old application (published in 2001) I am trying to get working in Windows 7/8/10. There is a setup.exe part of it that is using Java in some capacity, and not working correctly. I suspect it is using java because I decompiled the JAR file packaged with the application and there are references to several setup steps within the .java files (along with a file named setup.java). There is also a jre folder published with the application as well, running the following (dated) version:
F:\jre\bin>java -version
java version "1.3.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0_01)
Java HotSpot(TM) Client VM (build 1.3.0_01, mixed mode)
At first I suspected the application was using the systems environmental variables to use the currently installed version of JAVA, but I ruled that out by completely purging JAVA from the system and retesting - same results.
I next tried to simply update the folder to the latest version. As expected however, there were calls being made that were no longer supported (error message was referencing _JVM_IsVMGeneratedMethodl).
At this point I am running out of options. I could always run this application in a VM (and it works fine), but I would prefer to somehow package it in a nice streamlined way for easy distribution and install. Is there anything I can do? I was thinking something along the lines of application virtualization but still reading up on it.
It's hard to tell without "being there", but I'm guessing that the old (1.3) JVM just isn't compatible with the more modern versions of Windows.
Your best bet is probably running it against whatever version of Windows the app was originally developed on, in a VM.
If you have / can get the complete source code, you could try recompiling it with the version of Java supported on your current system. But it's probably a long-shot.
If it is containing a JRE folder, then you could skip the installer and add some batch file to launch that .jar with the specific JRE via a command of this form:
java -jar pathToYourJAR
btw, you could also consider options to convert to executable, some older are mentioned here:
How can I convert my Java program to an .exe file?
some of them may allow you to select which JRE to bundle/use
I am trying to launch an application (not Eclipse) that was written in Java. When I do, I get an error that says "Failed to Load the JNI shared Library (JDK)" along with a path that points to the location of the file.
From searching Google and StackOverflow, all I can find are people saying that the Java version installed needs to match my machine. My machine is 64 bit and so is my java installation, so I don't think that is my issue.
I have also verified that C:\Program Files\Java\jre7\bin is in my path variable. Also, just for the record, I do not use Eclipse. I have also tried uninstalling and reinstalling Java an the application that was written in Java. Lastly, the file it is complaining about exists on the machine.
Does anyone know what else could be the cause of this problem?
Update:
Thanks for your responses. I got it resolved, but the resolution seems like more of a hack and goes against what I was reading earlier. I installed the 32 bit version of Java 7 along side of my 64 bit version of Java 7. I then added the path the 32 bit version to the system path variable.
After I did this, the application was able to launch. Is there an issue with having both 64 bit and 32 bit versions of Java 7 installed simultaneously?
This is an error from your application. The application uses JNI. It is complaining that it cannot load it. Why it says (JDK) only its author knows. You will have to ask the author.
There is no problem having both versions of Java installed. However, the application you were using probably shipped with a 32-bit version of the JNI library. So, it needed to be used with a 32-bit Java JRE.
so I have this project in java that uses a jni .dll i wrote (which i've aptly named jniusb) that gives access to usb-hid devices. i've been using it for several months now without any notable issues until yesterday when i tried to launch my program from the jar instead of directly from netbeans. after a little debugging i characterized my issue as follows:
clicking on the jar icon starts my program without loading the dll. displaying the error messages in my gui revealed "no jniusb in java.library.path" even though i copied my dll to the java binaries folder (which always seemed to work in the past).
i tweaked the code to find the current directory and use "System.load" (with the dll copied to the same folder as my jar) instead of "System.loadLibrary". this approach threw the error "C:\Users\bpaik\Documents\NetBeansProjects\JniUsb\dist\jniusb.dll: Can't load AMD 64-bit .dll on a IA 32-bit platform". this made me scratch my head since i am most definitely working on an AMD 64-bit platform and running out of netbeans works with the same dll...
running the jar from the command prompt (with either java.exe or javaw.exe) loads the dll just fine. i thought that maybe this meant that i was having admin privileges issues so i tested the theory by going to the java executable and granting admin privileges, but this did not change anything. (and i'm also pretty sure i've used load/loadlibrary before without admin...)
i am no java expert so i've pretty much exhausted my debugging abilities and am now hoping that someone with a little more experience than i will recognize the issue i've described, thanks.
UPDATE: so i've fixed the problem but I still have no idea what is going on. i did a x86 build of my .dll and threw it into the folder with my jar and everything loaded/worked just fine. so i guess somehow (even though i set the default program for my jar to be the x64 JVM) the jar i built with the x64 library in Netbeans is running in a 32-bit JVM. to sum things up:
my jar is built with the x64 library in netbeans and runs fine with the x64 dll when launched from the command prompt.
when launching the jar from the icon (with default program set to x64 java) my program and JVM somehow switch to a 32-bit JVM and work fine when i use the 32-bit version of my dll.
trying to explicitly run my jar with the 32-bit java doesn't work at all. my gui doesn't display and the command prompt briefly opens/closes...
Problem 2 is certainly caused by you running a 32-bit JVM. Netbeans presumably runs a 64-bit JVM. You'll need to use something like Launch4j to get the right JVM loaded (or include both a 32-bit and 64-bit version of your DLL).
From the command line, try -d32 and -d64 to test that theory out.
Do you have multiple versions of Java installed on your Machine? It appears that when you run the jar by itself, your machine is creating a 32-bit VM for it. Open an command prompt and type java -version to check which version of Java is being used.
I am able to load a DLL library on my machine by putting it in a directory found in the PATH environment variable. I can also specify System.setProperty("jna.library.path","C:\\dev"); and that works. For some reason I cannot get it to work on another box that's running the same version of JBoss.
I tried dropping the DLL in C:\WINDOWS which is in the system PATH variable as well as a few other places and nothing works. Also, I tried putting it in C:\eclipse_dev\jboss-4.2.3.GA\bin which is in the user PATH variable.
The only differences between these machines are that mine is Win XP and the other that's not working is Windows server 2003 and also there are multiple users for windows server 2003, but I still have administrator privileges.
How is it failing? It could be missing dependent libraries. Try opening the DLL in the Dependency Walker tool. This will tell you whether there are dependent DLLs that can't be found on the system. If the DLL was compiled with Visual Studio, a likely culprit is that the Windows Server 2003 machine is missing the Visual C++ runtime DLLs which must be installed with the redistributable runtime package.