[JAVA] Wovon ich bei der Einführung der JNI-Bibliothek süchtig war

Einführung

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.

Umgebung

Java8 wildfly-8.1.0.Final

Was ist JNI?

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)

Informationen zur Installationsbibliothek

Der Hauptprozess ist eine externe Bibliothek, die in C ++ implementiert ist, und ich habe versucht, sie mithilfe von JNI in Java zu integrieren.

Ich war süchtig nach

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.

Umfrageergebnisse

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)

Korrespondenzteil ①

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

Korrespondenz Teil 2

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>

Korrespondenz ③

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>

Schließlich

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.

Referenz

Laden der WildFly-Klasse https://qiita.com/tama1/items/f1556886149722b87f78

Recommended Posts

Wovon ich bei der Einführung der JNI-Bibliothek süchtig war
Memorandum: Wovon ich süchtig war, als ich auf die Accounting Freee API traf
Was ich beim Update auf Spring Boot 1.5.12 behoben habe ・ Wovon ich süchtig war
Was ich mit der Redmine REST API süchtig gemacht habe
Die Geschichte, nach der ich beim Einrichten von STS süchtig war
Ich war süchtig nach der Rollmethode
Ich war süchtig nach dem Spring-Batch-Test
Wovon ich süchtig war, als ich die Google-Authentifizierung mit Rails implementierte
[Rails] Ich war süchtig nach den Nginx-Einstellungen, als ich Action Cable verwendete.
Eine Geschichte, der ich beim Testen der API mit MockMVC verfallen war
Probleme, denen ich beim Erstellen der Digdag-Umgebung mit Docker verfallen war
Ich war süchtig nach NoSuchMethodError in Cloud-Endpunkten
Ich war süchtig nach der Aufzeichnung des zugehörigen Modells
Ich war süchtig danach, sbt zu starten
Wovon ich süchtig war, als ich eine Spring Boot-Anwendung mit VS Code entwickelte
Wovon ich süchtig war, als ich rspec auf Schienen benutzte
Ich war süchtig danach, die Update-Anweisung in MyBatis zu wiederholen
Was ist zu tun, wenn in Eclipse "Fehler beim Laden der gemeinsam genutzten JNI-Bibliothek" angezeigt wird?
Ich war süchtig nach Laradock + VSCode + xdebug
Ich habe versucht zusammenzufassen, was bei der Site-Java-Ausgabe gefragt wurde.
Ein Hinweis, als ich süchtig danach war, Ubuntu auf WSL1 in WSL2 zu konvertieren
Über die Sache, dass ich süchtig danach war, wie man Hashmap benutzt
Ich war süchtig nach der API-Version min23 von registerTorchCallback
Ich war süchtig danach, in @ SpringApplicationConfiguration-> @SpringBootTest umzuschreiben
Vorstellung der Bibliothek
[Rails] So lösen Sie ActiveSupport :: MessageVerifier :: InvalidSignature, von dem ich bei der Einführung des Twitter-Logins abhängig war [ActiveStorage]
Was ich dachte, als ich den Eingabewert des Benutzers an die Service-Klasse übergab
Ich war süchtig danach, MySQL 8.0 mit einem 5.7-Gefühl zu berühren. My.cnf-Konfigurationsproblem
Ich war süchtig nach einem einfachen Test von Jedis (Java-> Redis-Bibliothek)
Aufgenommen, weil ich süchtig nach der Standardeingabe der Scannerklasse war
Ich war süchtig nach Scrollview, weil ich nicht auf die UIView mit variabler Größe tippen konnte
[Circle CI] Ich war süchtig nach dem automatischen Test von Circle CI (Rails + MySQL) [Memo]
Ich war süchtig nach Unit-Tests mit dem Pufferoperator in RxJava
Ich war süchtig nach RXTX mit Sierra
Ich war süchtig danach, onActivityResult () mit DialogFragment zu machen
Was ich getan habe, als ich Java zu Kotlin konvertiert habe
Was ich versucht habe, als ich alle Felder einer Bohne bekommen wollte
Ich war süchtig danach, vom Docker-Container aus keine Verbindung zu AWS-S3 herstellen zu können
Ich war ein wenig süchtig nach dem S3-Prüfsummenvergleich, machen Sie sich also eine Notiz.
Wir stellen vor, was ich gemacht habe, als ich RecyclerView eine Kopf- und Fußzeile hinzufügen wollte
Was tun, wenn das SSL-Zertifikat abgelaufen ist?
Was muss ich tun, um die aktualisierte Docker-Datei neu zu laden?
Beachten Sie, dass ich süchtig nach Stapelverarbeitung mit Spring Boot war
[Zusammenfassung] Was ich bemerkt und getan habe, als mir gesagt wurde, dass das Oracle JDK bezahlt wurde
Der Teil, dem ich in "Einführung in Ajax in Java-Webanwendungen" von NetBeans verfallen war
Beachten Sie, dass ich von den Einstellungen des Android-Projekts von IntelliJ IDEA abhängig war
Eine Geschichte, nach der ich süchtig war, als ich einen Schlüssel bekam, der automatisch auf MyBatis ausprobiert wurde
Ich wusste, was Reflexion war
Ich war süchtig danach, default_url_options mit der Einführung von Rails zu setzen
Als ich versuchte, mit JScrollBar automatisch zu scrollen, wurde der Ereignishandler nur einmal gezeichnet.
Ich war seltsamerweise süchtig danach, Javas Stream-API mit Scala zu verwenden
Ich war süchtig nach WSl, als ich versuchte, mit Vue.js eine Entwicklungsumgebung für Android-Anwendungen zu erstellen
Technische Ursachen und Gegenmaßnahmen für die Punkte, denen ich mit der ersten Android-App und Kotlin verfallen war
Was tun, wenn beim Versuch, mit Eclipse zu erstellen, ein Fehler in der gemeinsam genutzten JNI-Bibliothek auftritt?
[Circle CI] Eine Geschichte, der ich bei Start Building verfallen war