[JAVA] Ce à quoi j'étais accro lors de l'introduction de la bibliothèque JNI

introduction

J'étais accro au problème de ClassLoader lors de l'introduction de la bibliothèque externe de JNI dans le projet auquel je participe actuellement, je voudrais donc laisser une solution sous forme de mémorandum.

environnement

Java8 wildfly-8.1.0.Final

Qu'est-ce que JNI

Java Native Interface (JNI) est une plate-forme Java qui combine des programmes écrits en Java avec du code (code natif) écrit dans d'autres langages de programmation (tels que C ou C ++) qui s'exécute sur le processeur réel. C'est une spécification d'interface pour la coopération. (Cité de Wikipedia: https://ja.wikipedia.org/wiki/Java_Native_Interface)

À propos de la bibliothèque d'installation

Le processus principal est une bibliothèque externe implémentée en C ++, et j'essayais de l'intégrer dans Java en utilisant JNI.

J'étais accro à

Lorsque j'ai créé le matériau de construction, j'avais la configuration suivante.

service.ear
 ├ lib
 │ └ jni.pot ← Placez le pot JNI ici
 ├ META-INF
 ├ app1.jar
 ├ app2.jar
 └ webapp.war

Si vous déployez ce matériel sur WildFly et le démarrez, la première fois, cela fonctionne correctement. Le problème est que l'erreur suivante se produit lorsque le déploiement à chaud est effectué après la deuxième fois.

java.lang.UnsatisfiedLinkError: Native Library xxxx.dll already loaded in another classloader

"Il est déjà chargé dans un autre chargeur de classe" ... pourquoi ... Le redémarrage de WildFly résoudra ce problème, mais le déploiement à chaud se reproduira.

Résultats du sondage

Il semble y avoir une limitation selon laquelle les bibliothèques natives ne peuvent être chargées que dans un seul chargeur de classe. La première et la deuxième fois s'exécutent sur la même JVM, mais par conséquent, la même JVM est chargée deux fois car un chargeur de classe différent est utilisé à chaque fois qu'il est chargé, ce phénomène semble donc se produire. est. (Je l'ai interprété comme, mais veuillez préciser si c'est faux)

Partie correspondance ①

Suppression du fichier JNI jar du matériau de construction.

service.ear
├ lib ← Ne placez pas le pot JNI ici
 ├ META-INF
 ├ app1.jar
 ├ app2.jar
 └ webapp.war

Correspondance partie 2

Placez le pot en tant que module statique dans WildFly.

wildfly-8.1.0.Final/modules/system/layers/base配下にフォルダを作成します。 (例)wildfly-8.1.0.Final/modules/system/layers/base/xxx/yyy/main

Placez le fichier jar et module.xml dans le dossier créé.

base/xxx/yyy/main
 ├ jni.jar
 └ module.xml ← Créer un nouveau fichier

Le contenu de module.xml. Faites correspondre le nom de la balise madule avec la structure de répertoires créée ci-dessus.

<?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>

Correspondance ③

Ajoutez une dépendance à jboss-deployment-structure.xml.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="xxx.yyy" export="true" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>

finalement

Avec la prise en charge ci-dessus, l'erreur Class Loader n'apparaît plus même après le déploiement à chaud. Puisqu'il n'y avait pas d'autres membres autour du middleware, j'ai désespérément enquêté dessus, alors j'ai décidé de le laisser comme un rappel. Je ne sais pas si cette réponse est vraiment correcte, mais je suis heureux que le problème ait été résolu pour le moment.

référence

Chargement de la classe WildFly https://qiita.com/tama1/items/f1556886149722b87f78

Recommended Posts

Ce à quoi j'étais accro lors de l'introduction de la bibliothèque JNI
Mémorandum: Ce à quoi j'étais accro quand j'ai frappé l'API de comptabilité freee
Ce que j'ai corrigé lors de la mise à jour vers Spring Boot 1.5.12 ・ Ce à quoi j'étais accro
Ce à quoi j'étais accro avec l'API REST Redmine
L'histoire à laquelle j'étais accro lors de la création de STS
J'étais accro à la méthode du rouleau
J'étais accro au test Spring-Batch
Ce à quoi j'étais accro lors de la mise en œuvre de l'authentification Google avec des rails
[Rails] J'étais accro aux paramètres nginx lors de l'utilisation d'Action Cable.
Une histoire à laquelle j'étais accro lors du test de l'API à l'aide de MockMVC
Problèmes auxquels j'étais accro lors de la création de l'environnement digdag avec docker
J'étais accro à NoSuchMethodError dans Cloud Endpoints
J'étais accro au record du modèle associé
J'étais accro au démarrage de sbt
Ce à quoi j'étais accro lors du développement d'une application Spring Boot avec VS Code
Ce à quoi j'étais accro en utilisant rspec sur des rails
J'étais accro à la mise à jour de la déclaration dans MyBatis
Que faire lorsque «Échec du chargement de la bibliothèque partagée JNI» s'affiche dans Eclipse
J'étais accro au réglage de laradock + VSCode + xdebug
J'ai essayé de résumer ce qui était demandé lors de l'édition site-java-
Une note quand j'étais accro à la conversion d'Ubuntu sur WSL1 en WSL2
À propos de la question pour laquelle j'étais accro à l'utilisation de hashmap
J'étais accro au paramètre API version min23 de registerTorchCallback
J'étais accro à la réécriture sur @ SpringApplicationConfiguration-> @SpringBootTest
Présentation de la bibliothèque
[Rails] Comment résoudre ActiveSupport :: MessageVerifier :: InvalidSignature auquel j'étais accro lors de l'introduction de la connexion Twitter [ActiveStorage]
Ce que j'ai pensé en passant la valeur d'entrée de l'utilisateur à la classe Service
J'étais accro à l'idée de toucher MySQL 8.0 avec un sentiment de 5.7. Problème de configuration My.cnf
J'étais accro à un simple test de Jedis (bibliothèque Java-> Redis)
Enregistré parce que j'étais accro à l'entrée standard de la classe Scanner
J'étais accro au scrollview car je ne pouvais pas appuyer sur la taille variable UIView
[Circle CI] J'étais accro au test automatique de Circle CI (rails + mysql) [Memo]
J'étais accro aux tests unitaires avec l'opérateur de tampon dans RxJava
J'étais accro à l'utilisation de RXTX avec Sierra
J'étais accro à faire onActivityResult () avec DialogFragment
Ce que j'ai fait lorsque j'ai converti Java en Kotlin
Ce que j'ai essayé quand je voulais obtenir tous les champs d'un haricot
J'étais accro à ne pas pouvoir me connecter à AWS-S3 à partir du conteneur Docker
J'étais un peu accro à la comparaison S3 Checksum, alors prenez note.
Présentation de ce que j'ai fait lorsque je voulais ajouter un en-tête et un pied de page à RecyclerView
Que faire lorsque le certificat SSL a expiré
Que dois-je faire pour recharger le Dockerfile mis à jour?
Notez que j'étais accro au traitement par lots avec Spring Boot
[Résumé] Ce que j'ai remarqué et fait quand on m'a dit que le JDK Oracle était payé
La partie à laquelle j'étais accro dans "Introduction à Ajax dans les applications Web Java" de NetBeans
Notez que j'étais accro aux paramètres du projet Android d'IntelliJ IDEA
Une histoire à laquelle j'étais accro lors de l'obtention d'une clé qui a été automatiquement essayée sur MyBatis
Je savais ce qu'était la réflexion
J'étais accro à la configuration de default_url_options avec l'introduction de la conception de Rails
Lorsque j'ai essayé de faire défiler automatiquement avec JScrollBar, le gestionnaire d'événements n'a été dessiné qu'une seule fois.
J'étais étrangement accro à l'utilisation de l'API Stream de Java avec Scala
J'étais accro à WSl en essayant de créer un environnement de développement d'applications Android avec Vue.js
Causes techniques et contre-mesures pour les points auxquels j'étais accro avec la première application Android et Kotlin
Que faire si vous obtenez une erreur de bibliothèque partagée JNI lorsque vous essayez de créer avec Eclipse
[Circle CI] Une histoire à laquelle j'étais accro chez Start Building