I am using the Java Native Interface to include some statically compiled code in with my Java application. Particularly, I've got a DLL file with the compiled code in the WAR that contains my application.
Unfortunately, the class loader can't load the DLL from inside the WAR (from preliminary research... if this is wrong, be sure to tell me!). So I have to copy the DLL out to a temporary folder, and then load it from there.
But when I then try and load the copied DLL, I get java.lang.UnsatisfiedLinkError: C:\path\to\dll\VIX.dll: %1 is not a valid Win32 application
. The file sizes look the same (both 401K, according to Windows), but it just doesn't work. Here's the code that does the copying:
InputStream ReadDLL = Thread.currentThread().getContextClassLoader().getResourceAsStream("/VIX.dll");
File file = new File(workDir, "VIX.dll");
OutputStream WriteDLL = null;
try {
WriteDLL = new FileOutputStream(file);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] buffer = new byte[1024];
int numchars;
try {
while((numchars = ReadDLL.read(buffer)) > 0) {
WriteDLL.write(buffer, 0, numchars);
}
ReadDLL.close();
WriteDLL.close();
} catch (IOException e) {
e.printStackTrace();
}
Comparing the original and the copied versions of the DLL, I find that every instance of the byte 0x0A (The ASCII linefeed character) in the original is being replaced with two bytes: 0x0D0A (An ASCII CRLF). Of course, this being a DLL, the 0x0A is not actually a linefeed, just a binary opcode. But for some reason, Java insists on doing this helpful translation for me.
Finally, the ReadDLL InputStream is being obtained by calling Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
where, obviously, fileName
is the name of my file.