Peut-être que cela aidera quelqu'un parce que ça marche plutôt bien pour moi. Le problème peut être résolu en intégrant vos propres dépendances. Suivez ces étapes simples
Vérifiez d'abord l'erreur qui devrait ressembler à ceci :
- Échec de l'exécution de la méthode :
- java.lang.LinkageError :violation de la contrainte du chargeur :
- lors de la résolution de la méthode "org.slf4j.impl.StaticLoggerBinder .getLoggerFactory()Lorg/slf4j/ILoggerFactory;"
- le chargeur de classe (instance de org/openmrs/module/ModuleClassLoader) de la classe actuelle, org/slf4j/LoggerFactory ,
- et le chargeur de classe (instance de org/apache/catalina/loader/WebappClassLoader) pour la classe résolue, org/slf4j/impl/StaticLoggerBinder ,
- avoir différents objets Class pour le type taticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory ; utilisé dans la signature
-
Voir les deux classes en surbrillance. Google les recherche comme "Téléchargement de jar StaticLoggerBinder.class" et "Téléchargement de jar LoggeraFactory.class". Cela vous montrera le premier ou dans certains cas le deuxième lien (le site est http://www.java2s.com ) qui est l'une des versions jar que vous avez incluses dans votre projet. Vous pouvez l'identifier intelligemment vous-même, mais nous sommes accros à Google ;)
-
Après cela, vous connaîtrez le nom du fichier jar, dans mon cas, c'est comme slf4j-log4j12-1.5.6.jar &slf4j-api-1.5.8
- Maintenant, la dernière version de ce fichier est disponible ici http://mvnrepository.com/ (en fait, toutes les versions jusqu'à ce jour, c'est le site à partir duquel maven obtient vos dépendances).
- Ajoutez maintenant les deux fichiers en tant que dépendances avec la dernière version (ou conservez la même version des deux fichiers, l'une ou l'autre des versions choisies est ancienne). Voici la dépendance que vous devez inclure dans pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
Pouvez-vous spécifier un chargeur de classe ? Sinon, essayez de spécifier le chargeur de classe de contexte comme suit :
Thread thread = Thread.currentThread();
ClassLoader contextClassLoader = thread.getContextClassLoader();
try {
thread.setContextClassLoader(yourClassLoader);
callDom4j();
} finally {
thread.setContextClassLoader(contextClassLoader);
}
Je ne connais pas le Java Plugin Framework, mais j'écris du code pour Eclipse et je rencontre de temps en temps des problèmes similaires. Je ne garantis pas que ça va le réparer, mais ça vaut probablement le coup.
Cela ressemble à un problème de hiérarchie de classloader. Je ne peux pas dire dans quel type d'environnement votre application est déployée, mais parfois ce problème peut se produire dans un environnement Web - où le serveur d'applications crée une hiérarchie de classloaders, ressemblant à quelque chose comme :
javahome/lib - en tant que root
appserver/lib - en tant qu'enfant de root
webapp/WEB-INF/lib - en tant qu'enfant de l'enfant de la racine
etc
Habituellement, les chargeurs de classe délèguent le chargement à leur chargeur de classe parent (c'est ce qu'on appelle "parent-first
"), et si ce chargeur de classe ne peut pas trouver la classe, alors le chargeur de classe enfant tente de le faire. Par exemple, si une classe déployée en tant que JAR dans webapp/WEB-INF/lib essaie de charger une classe, il demande d'abord au chargeur de classe correspondant à appserver/lib pour charger la classe (qui à son tour demande au chargeur de classe correspondant à javahome/lib de charger la classe), et si cette recherche échoue, alors WEB-INF/lib est recherché pour une correspondance avec cette classe.
Dans un environnement Web, vous pouvez rencontrer des problèmes avec cette hiérarchie. Par exemple, une erreur/un problème que j'ai rencontré auparavant était lorsqu'une classe dans WEB-INF/lib dépendait d'une classe déployée dans appserver/lib, qui à son tour dépendait d'une classe déployée dans WEB-INF/lib. Cela provoquait des échecs car, bien que les chargeurs de classe puissent déléguer au chargeur de classe parent, ils ne peuvent pas déléguer vers le bas de l'arborescence. Ainsi, le chargeur de classe WEB-INF/lib demanderait au chargeur de classe appserver/lib une classe, le chargeur de classe appserver/lib chargerait cette classe et essaierait de charger la classe dépendante, et échouerait car il ne pouvait pas trouver cette classe dans appserver/lib ou javahome /lib.
Ainsi, bien que vous ne déployiez peut-être pas votre application dans un environnement de serveur Web/d'application, mon explication trop longue peut s'appliquer à vous si votre environnement a une hiérarchie de chargeurs de classe configurés. Est-ce le cas ? Est-ce que JPF fait une sorte de magie de chargeur de classe pour pouvoir implémenter ses fonctionnalités de plugin ?
LinkageError est ce que vous obtiendrez dans un cas classique où vous avez une classe C chargée par plus d'un chargeur de classe et ces classes sont utilisées ensemble dans le même code (comparé, cast, etc.). Peu importe qu'il s'agisse du même nom de classe ou même s'il est chargé à partir du même fichier jar - une classe d'un chargeur de classe est toujours traitée comme une classe différente si elle est chargée à partir d'un autre chargeur de classe.
Le message (qui s'est beaucoup amélioré au fil des ans) indique :
Exception in thread "AWT-EventQueue-0" java.lang.LinkageError:
loader constraint violation in interface itable initialization:
when resolving method "org.apache.batik.dom.svg.SVGOMDocument.createAttribute(Ljava/lang/String;)Lorg/w3c/dom/Attr;"
the class loader (instance of org/java/plugin/standard/StandardPluginClassLoader)
of the current class, org/apache/batik/dom/svg/SVGOMDocument,
and the class loader (instance of ) for interface org/w3c/dom/Document
have different Class objects for the type org/w3c/dom/Attr used in the signature
Donc, ici, le problème est de résoudre la méthode SVGOMDocument.createAttribute(), qui utilise org.w3c.dom.Attr (partie de la bibliothèque DOM standard). Mais, la version d'Attr chargée avec Batik a été chargée à partir d'un chargeur de classe différent de l'instance d'Attr que vous passez à la méthode.
Vous verrez que la version de Batik semble être chargée à partir du plugin Java. Et le vôtre est chargé à partir de " ", qui est très probablement l'un des chargeurs JVM intégrés (boot classpath, ESOM ou classpath).
Les trois principaux modèles de chargeur de classe sont :
- délégation (la valeur par défaut dans le JDK - demander au parent, puis à moi)
- post-délégation (courante dans les plugins, les servlets et les endroits où vous voulez l'isolement - demandez-moi, puis parent)
- frère (courant dans les modèles de dépendance comme OSGi, Eclipse, etc.)
Je ne sais pas quelle stratégie de délégation le chargeur de classe JPF utilise, mais la clé est que vous voulez qu'une version de la bibliothèque dom soit chargée et que tout le monde se procure cette classe à partir du même emplacement. Cela peut signifier le supprimer du chemin de classe et le charger en tant que plugin, ou empêcher Batik de le charger, ou autre chose.