2010-09-02 25 views
1

J'utilise Java Native Interface pour inclure du code compilé statiquement dans mon application Java. En particulier, j'ai un fichier DLL avec le code compilé dans le fichier WAR qui contient mon application.La copie de DLL à partir de WAR entraîne la création de CRLF par les LF

Malheureusement, le chargeur de classe ne peut pas charger la DLL depuis l'intérieur du WAR (à partir de recherches préliminaires ... si cela est faux, assurez-vous de me le dire!). Je dois donc copier la DLL dans un dossier temporaire, puis le charger à partir de là.

Mais lorsque j'essaie ensuite de charger la DLL copiée, j'obtiens java.lang.UnsatisfiedLinkError: C:\path\to\dll\VIX.dll: %1 is not a valid Win32 application. La taille des fichiers est la même (401 Ko, selon Windows), mais cela ne fonctionne tout simplement pas. Voici le code qui fait la copie:

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

En comparant l'original et les versions copiées de la DLL, je trouve que tous les cas de l'octet 0x0A (Le caractère de saut de ligne ASCII) dans l'original est remplacé par deux octets : 0x0D0A (un CRLF ASCII). Bien sûr, ceci étant une DLL, le 0x0A n'est pas en fait un saut de ligne, juste un opcode binaire. Mais pour une raison quelconque, Java insiste pour faire cette traduction utile pour moi.

Enfin, le ReadDLL InputStream est obtenu en appelant Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); où, évidemment, fileName est le nom de mon fichier.

+0

Que sont ReadDLL et WriteDLL? – Herms

+0

Instances d'InputStream et OutputStream, respectivement. – Hober

+0

Pouvez-vous ajouter les lignes où vous les créez et ouvrez les fichiers? Cela pourrait facilement faire partie du problème. – Herms

Répondre

0

Deux hypothèses:

  1. Peut-être que la DLL a été modifié par un transfert FTP UNIX vers Windows en utilisant le mode ASCII par défaut (utilisez le mode bin pour le transfert FTP).
  2. Peut-être que la DLL a été traitée comme un fichier ASCII dans un système de contrôle de révision et a été extraite sur un système Windows.

Essayez de décompresser le fichier WAR et de voir s'il s'agit de la version originale ou modifiée.

Je ne vois aucun cas où Java ou le serveur webapp effectuerait cette conversion dans votre dos.

+0

Je génère la DLL localement, sur mon ordinateur Windows, en compilant avec le compilateur Visual Studio CL.Il est ensuite compressé dans le fichier WAR par un script de génération ANT (en utilisant l'action "zip") et copié dans un autre répertoire. De là, le WAR est décompressé par un autre programme et lu, qui exécute ce code. J'ai vérifié la version de la DLL dans le zip, et la version de la DLL dans le dossier temporaire (où il a été décompressé par l'application). Aucun n'a ce problème. – Hober

+0

Quel est votre serveur d'applications Web? – gawi

+0

Jetty lance le servlet dont ce code fait partie. – Hober