tags:

views:

30

answers:

1

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.

A: 

Two hypotheses:

  1. Maybe the DLL was modified by an UNIX-to-Windows FTP transfer using default ASCII mode (use the bin mode for FTP transfer).
  2. Maybe the DLL was treated as an ASCII file in a revision control system and was checked out on a Windows system.

Try to unzip the WAR and see if it's the original or modified version.

I don't see any case where Java or the webapp server would perform that conversion in your back.

gawi
I'm generating the DLL locally, on my Windows machine, compiling with the Visual Studio CL compiler. It then gets zipped in to the WAR by an ANT build script (using the "zip" action) and copied to another directory. From there, the WAR is unpacked by another program and read, which runs this code. I've checked both the version of the DLL in the zip, and the version of the DLL in the temp folder (where it was unzipped by the application). Neither have this problem.
Hober
What's you web application server?
gawi
Jetty is running the servlet that this code is a part of.
Hober