Ich verwende den kürzlich veröffentlichten Glassfish v3 und während ich native Bibliotheken benutze, würde sich glassfish zeitweise beschweren
%Vor%Die Prozedur zum Laden nativer Bibliotheken in der vorherigen Glassfish-Version (v2.2) bestand darin, die DLL-Dateien einfach in GLASSFISH_HOME \ lib abzulegen. Jetzt weiß ich nicht, ob es in v3 einen solchen magischen Ordner gibt und ob es etwas zu erzählen gibt. Ich habe auch den Admin-Bildschirm überprüft und es gibt zwei Variablen, von denen ich denke, dass sie mit meinem Problem zusammenhängen: Native Library Path Prefix und Native Library Path Suffix. Ich habe das Internet durchforstet, um eine angemessene Beschreibung dessen zu finden, was sie tun und wie ich sie verwenden sollte, aber anscheinend redet niemand gerne darüber.
%Vor%
Eine native Lib kann nur einmal in der JVM geladen werden und Sie erhalten diese Fehlermeldung, wenn Sie eine neue Version der aufrufenden Klasse laden (die Klasse, in der System.loadLibrary(String)
Aufruf bleibt) bei einer erneuten Bereitstellung. Mehr dazu unten.
Um native Bibliotheken in der vorherigen glassfish-Version (v2.2) zu laden, mussten einfach die .dll-Dateien in
GLASSFISH_HOME\lib
eingefügt werden.
Nun, das ist eigentlich nur der erste Teil der Geschichte. Um eine native Bibliothek zu laden, müssen Sie sie natürlich auf den Bibliothekspfad und setzen, um sie aus dem Java-Code zu laden. Um dies zu tun, sollte die Konvention einen statischen Initialisierer enthalten:
%Vor% Wenn Sie mit einer Webanwendung arbeiten, empfiehlt es sich, die nativen Bibliotheken ODER ihre JNI-Schnittstellen nicht unter WEB-INF/lib
oder WEB-INF/classes
zu platzieren, um Probleme beim erneuten Laden der Anwendung zu vermeiden, wie oben erwähnt. Mit anderen Worten, die Klasse, die aufruft System.loadLibrary(String)
sollte von einem Klassenlader geladen werden, der nicht durch das erneute Laden der Webanwendung selbst betroffen ist.
Also meine Frage ist: Wo hast du diesen Code?
PS: Eine andere Möglichkeit wäre, zu prüfen, ob die DLL bereits verfügbar ist, bevor sie geladen wird, aber das würde ich nicht tun.
Als erstes: Eine gegebene native Klasse kann nur in einen Klassenlader geladen werden.
Zweitens: Jede Web-App in einem Servlet-Container hat ihren eigenen Klassenlader.
Drittens: Sie müssen beim Codieren von nativem Code sehr vorsichtig sein, damit seine Klassen als Garbage Collected erfasst werden können.
Ergebnis: Sobald Sie systemeigenen Code in eine Webanwendung laden, erhalten Sie wahrscheinlich diese Fehler, wenn Sie versuchen, sie zu entladen und neu zu laden.
Ich überspringe in gewisser Weise die wirklich einfache Variante dieses Themas: Einfach zwei verschiedene Webapps mit derselben nativen Klasse laden.
Einige Leute ziehen es vor, systemeigenen Code in den Systemklassenlader zu laden, um dieses Problem zu vermeiden.