从 WAR 中复制 DLL 会导致 LF 变成 CRLF

发布于 2024-09-17 11:25:13 字数 1244 浏览 5 评论 0原文

我正在使用 Java 本机接口在我的 Java 应用程序中包含一些静态编译的代码。特别是,我有一个 DLL 文件,其中包含我的应用程序的 WAR 中的编译代码。

不幸的是,类加载器无法从 WAR 内部加载 DLL(根据初步研究...如果这是错误的,请务必告诉我!)。所以我必须将 DLL 复制到临时文件夹,然后从那里加载它。

但是,当我尝试加载复制的 DLL 时,出现 java.lang.UnsatisfiedLinkError: C:\path\to\dll\VIX.dll: %1 不是有效的 Win32 应用程序。文件大小看起来相同(根据 Windows,均为 401K),但就是行不通。下面是执行复制的代码:

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();
}

比较 DLL 的原始版本和复制版本,我发现原始版本中字节 0x0A(ASCII 换行符)的每个实例都被替换为两个字节:0x0D0A(ASCII CRLF) 。当然,这是一个 DLL,0x0A 实际上并不是换行符,只是一个二进制操作码。但出于某种原因,Java 坚持为我做这个有用的翻译。

最后,通过调用 Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); 获取 ReadDLL InputStream,显然,fileName 是我的文件的名称。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

早茶月光 2024-09-24 11:25:13

两个假设:

  1. 也许 DLL 是通过使用默认 ASCII 模式(使用 bin 模式进行 FTP 传输)的 UNIX 到 Windows FTP 传输修改的。
  2. 也许 DLL 在修订控制系统中被视为 ASCII 文件,并在 Windows 系统上检出。

尝试解压 WAR 并查看它是原始版本还是修改版本。

我没有看到任何 Java 或 webapp 服务器会在你背后执行该转换的情况。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文