2010-09-02 34 views
1

我正在使用Java本地接口將一些靜態編譯的代碼包含在我的Java應用程序中。特別是,我有一個包含我的應用程序的WAR中的編譯代碼的DLL文件。從WAR複製DLL導致LF變爲CRLF

不幸的是,類加載器無法從WAR內部加載DLL(從初步研究...如果這是錯誤的,一定要告訴我!)。所以我必須將DLL複製到一個臨時文件夾,然後從那裏加載它。

但是,當我然後嘗試加載複製的DLL,我得到java.lang.UnsatisfiedLinkError: C:\path\to\dll\VIX.dll: %1 is not a valid Win32 application。根據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是我的文件的名稱。

+0

什麼是ReadDLL和WriteDLL? – Herms 2010-09-02 18:01:38

+0

分別是InputStream和OutputStream的實例。 – Hober 2010-09-02 18:08:22

+0

你可以添加你創建它們並打開文件的行嗎?這很可能是問題的一部分。 – Herms 2010-09-02 18:09:09

回答

0

兩個假設:

  1. 也許DLL是使用默認的ASCII模式(使用bin模式FTP傳輸)的UNIX到Windows FTP傳輸修改。
  2. 也許該DLL在修訂控制系統中被視爲ASCII文件,並在Windows系統上檢出。

嘗試解壓WAR,看看它是原始的還是修改後的版本。

我沒有看到Java或webapp服務器會在您的背後執行轉換的任何情況。

+0

我在Windows機器上本地生成DLL,使用Visual Studio CL編譯器進行編譯。然後通過ANT構建腳本(使用「zip」操作)將其壓縮到WAR中並複製到另一個目錄。從那裏,WAR被另一個程序解壓並讀取,它運行這個代碼。我已經在zip中檢查了DLL的版本,並且在臨時文件夾(它由應用程序解壓縮的地方)中檢查了DLL的版本。這個問題也沒有。 – Hober 2010-09-03 02:31:34

+0

什麼是您的Web應用程序服務器? – gawi 2010-09-03 16:34:13

+0

Jetty正在運行此代碼所屬的servlet。 – Hober 2010-09-07 13:53:59