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.
Java8 wildfly-8.1.0.Final
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)
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.
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.
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)
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
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>
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>
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.
Chargement de la classe WildFly https://qiita.com/tama1/items/f1556886149722b87f78
Recommended Posts