Ich war süchtig nach dem ClassLoader-Problem, als ich die externe Bibliothek von JNI in das Projekt einführte, an dem ich gerade teilnehme. Daher möchte ich eine Lösung als Memorandum hinterlassen.
Java8 wildfly-8.1.0.Final
Das Java Native Interface (JNI) ist eine Java-Plattform, die in Java geschriebene Programme mit Code (nativem Code) kombiniert, der in anderen Programmiersprachen (wie C oder C ++) geschrieben ist und auf der tatsächlichen CPU ausgeführt wird. Es ist eine Schnittstellenspezifikation für die Zusammenarbeit. (Zitiert aus Wikipedia: https://ja.wikipedia.org/wiki/Java_Native_Interface)
Der Hauptprozess ist eine externe Bibliothek, die in C ++ implementiert ist, und ich habe versucht, sie mithilfe von JNI in Java zu integrieren.
Als ich das Baumaterial erstellte, hatte ich die folgende Konfiguration.
service.ear
├ lib
│ └ jni.jar ← Platziere das JNI-Glas hier
├ META-INF
├ app1.jar
├ app2.jar
└ webapp.war
Wenn Sie dieses Material für WildFly bereitstellen und starten, funktioniert es beim ersten Mal einwandfrei. Das Problem besteht darin, dass der folgende Fehler auftritt, wenn Hot Deploy nach dem zweiten Mal ausgeführt wird.
java.lang.UnsatisfiedLinkError: Native Library xxxx.dll already loaded in another classloader
"Es ist bereits in einem anderen Klassenlader geladen" ... warum ... Durch einen Neustart von WildFly wird dieses Problem behoben, Hot Deploy wird jedoch erneut ausgeführt.
Es scheint eine Einschränkung zu geben, dass native Bibliotheken nur in einen Klassenlader geladen werden können. Das erste und das zweite Mal werden auf derselben JVM ausgeführt, aber jedes Mal, wenn sie geladen wird, wird ein anderer Klassenlader verwendet. Infolgedessen wird dieselbe JVM zweimal geladen, sodass dieses Phänomen aufzutreten scheint. ist. (Ich habe es als interpretiert, aber bitte weisen Sie darauf hin, wenn es falsch ist)
Die JNI-JAR-Datei wurde aus dem Build-Material entfernt.
service.ear
├ lib ← Stellen Sie hier kein JNI-Glas auf
├ META-INF
├ app1.jar
├ app2.jar
└ webapp.war
Platzieren Sie das Glas als statisches Modul in WildFly.
wildfly-8.1.0.Final/modules/system/layers/base配下にフォルダを作成します。 (例)wildfly-8.1.0.Final/modules/system/layers/base/xxx/yyy/main
Legen Sie die JAR-Datei und die Datei module.xml in den erstellten Ordner.
base/xxx/yyy/main
├ jni.jar
└ module.xml ← Erstelle eine neue Datei
Der Inhalt von module.xml. Ordnen Sie den Namen des madule-Tags der oben erstellten Verzeichnisstruktur zu.
<?xml version="1.0" encoding="UTF-8"?>
<module name="xxx.yyy" xmlns="urn:jboss:module:1.1">
<resources>
<resource-root path="jni.jar"/>
</resources>
</module>
Fügen Sie eine Abhängigkeit zu jboss-deploy-struct.xml hinzu.
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="xxx.yyy" export="true" />
</dependencies>
</deployment>
</jboss-deployment-structure>
Mit der oben genannten Unterstützung wird der Class Loader-Fehler auch nach Hot Deploy nicht mehr angezeigt. Da es keine anderen Mitglieder in der Nähe der Middleware gab, habe ich sie verzweifelt untersucht und beschlossen, sie als Erinnerung zu belassen. Ich bin mir nicht sicher, ob diese Antwort wirklich richtig ist, aber ich bin froh, dass das Problem vorerst behoben wurde.
Laden der WildFly-Klasse https://qiita.com/tama1/items/f1556886149722b87f78
Recommended Posts