0

I have a JavaFX application which I deploy as a JAR. The application loads and uses native library (a JNI interface).

The DLL is expected to be in the same directory as the JAR. This is how I load the library. I have verified that the path is always correct to the DLL.

            String jarPath = ClassLoader.getSystemClassLoader().getResource(".").getPath();
            System.out.println(jarPath);
            System.load(jarPath + "_JNI.dll");

Here is the issue: When I execute java to run the jar from the same directory as the jar, it works fine. When I execute java to run the jar from an outside directory, it throws:

java.lang.UnsatisfiedLinkError: C:/Test/_JNI.dll: %1 is not a valid Win32 application at java.lang.ClassLoader$NativeLibrary.load(Native Method)

For example:

::This works. The dll loads and executes successfully.
cd C:/test
java -jar PDWIN.jar

::This does not work. UnsatisifedLinkerror
java -jar "C:/test/PDWIN.jar"

My thoughts were that there were bitness differences in components, or the JNI method signatures were wrong, but this is not true, I have verified that the JVM is 64 bit, and the DLL is 64 bit.

The fact that the DLL works fine when I run java from inside the directory containing the JAR, but doesn't work when I run from outside is strange... (note: I print the path 'jarPath' and it is the same correct path in both cases)

James Wierzba
  • 16,176
  • 14
  • 79
  • 120

1 Answers1

0

The problem is: Windows automatically searches for DLLs in the system directories and the current working directory. In the first example the working directory is set correctly in the second it is not.

There are multiple solutions to this: Creating a start script that allways changes the working directory is probably the simplest.

My prefered solution would be: Put the DLL inside the jar. Use the Classloader to open the DLL as an InputStream, copy it in a tempfile and load this tempfile with an absolute system path. (see here: Extract and load DLL from JAR)

This solution can even be adapted to work on different platforms.

Community
  • 1
  • 1
  • I am explicitly loading the DLL via System.load() from the directory the jar is located in, NOT the working directory. I have verified that the path to the DLL is indeed correct via a print statement (yet it still throws an error). How will changing the working directory have any effect on this? – James Wierzba Jun 04 '15 at 16:50