2012-08-01 1 views
13

Cette question ressemble à similar questions sur les sites SE, donc je devrais être assez bavard pour clarifier ma question. Donc, voici projet de minimum pom.xml:Résoudre plusieurs liaisons SLF4J dans le projet maven

<dependencies> 
    <dependency> 
     <groupId>ch.qos.logback</groupId> 
     <artifactId>logback-classic</artifactId> 
     <version>1.0.6</version> 
    </dependency> 

    <dependency> 
     <groupId>org.codehaus.gmaven.runtime</groupId> 
     <artifactId>gmaven-runtime-1.7</artifactId> 
     <version>1.3</version> 
    </dependency> 

</dependencies> 
<build> 
    <plugins> 
     <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>exec-maven-plugin</artifactId> 
      <version>1.2.1</version> 
      <configuration> 
       <mainClass>org.shabunc.App</mainClass> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

Voici l'arbre de dépendance produit par Maven.

mvn dependency:tree -Dverbose -Dincludes=org.slf4j:

[INFO] [dependency:tree {execution: default-cli}] 
[INFO] org.shabunc:logdebug:jar:1.0-SNAPSHOT 
[INFO] \- ch.qos.logback:logback-classic:jar:1.0.6:compile 
[INFO] \- org.slf4j:slf4j-api:jar:1.6.5:compile 

Maintenant, nous allons supprimer l'exclusion et vérifier les dépendances à nouveau. Nous obtiendrons:

[INFO] org.shabunc:logdebug:jar:1.0-SNAPSHOT 
[INFO] +- ch.qos.logback:logback-classic:jar:1.0.6:compile 
[INFO] | \- org.slf4j:slf4j-api:jar:1.6.5:compile 
[INFO] \- org.codehaus.gmaven.runtime:gmaven-runtime-1.7:jar:1.3:compile 
[INFO] +- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5) 
[INFO] +- org.codehaus.gmaven.feature:gmaven-feature-support:jar:1.3:compile 
[INFO] | \- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5) 
[INFO] \- org.codehaus.gmaven.runtime:gmaven-runtime-support:jar:1.3:compile 
[INFO]  +- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5) 
[INFO]  \- org.sonatype.gshell:gshell-io:jar:2.0:compile 
[INFO]   \- org.sonatype.gossip:gossip:jar:1.0:compile 
[INFO]    \- (org.slf4j:slf4j-api:jar:1.5.8:compile - omitted for conflict with 1.6.5) 

Ainsi, comme nous pouvons le voir, tout fonctionne comme prévu, et la dépendance conflictuelle est en fait exclue. Mais la chose est que même avec la dépendance exclu que je reçois toujours le message suivant lors de la compilation et l'appel mvn exec:java:

SLF4J: Class path contains multiple SLF4J bindings. 
SLF4J: Found binding in [jar:file:/home/shabunc/.m2/repository/ch/qos/logback/logback-classic/1.0.6/logback-classic-1.0.6.jar!/org/slf4j/impl/StaticLoggerBinder.class] 
SLF4J: Found binding in [jar:file:/home/shabunc/.m2/repository/org/sonatype/gossip/gossip/1.0/gossip-1.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] 

La question est: Pourquoi je vois encore cet avertissement et ce qu'il faut faire exactement pour faire qu'une seule version de slf4j accessible lors de l'exécution?

+1

Aucune infraction intentionnelle, mais la déclaration d'une dépendance sur slf4j-api, puis à l'exclusion de slf4j-api est erronée. L'instruction suivante est également incorrecte. "faisons en sorte que slf4j-api soit chargé seulement une fois, comme nous nous y attendions quand nous avons ajouté des exclusions/exclusions à la partie à la dépendance gmaven-runtime." Lorsque des dépendances déclarent des versions différentes d'un artefact, par exemple . slf4j-api, Maven ne placera pas slf4j-api plusieurs fois sur le chemin de la classe. Même si Maven l'a fait (ce qui n'est pas le cas pour ), slf4j-api ne serait pas chargé plusieurs fois. S'il vous plaît éditez votre question afin de ne pas tromper les futurs lecteurs. – Ceki

+0

Ceki, ce sera OK même si ce sera l'offense qui va m'apprendre quelque chose))) Le fait est slf4j-api est chargé plusieurs fois créant ainsi des conflits lorsque je tente de déployer comme guerre à tomcat. Un slf4j est dans logblack et un dans la dépendance de la dépendance de gmaven-runtime. S'il me manque quelque chose, ce sera très gentil de votre part si vous le clarifiez, puisque toute cette résolution de dépendance n'est pas la chose dans laquelle je suis expert. – shabunc

+0

Si vous utilisez Maven, il n'y a aucun risque que des versions différentes de slf4j-api soient présentes sur votre chemin de classe. Cependant, il est courant pour différentes reliures slf4j *, par ex. slf4j-jdj14.jar, slf4j-log4j.jar ou logback-classic.jar pour être présents simultanément sur le chemin de la classe. Dans votre cas, vous avez le fichier logback-classic-1.0.6.jar gossip-1.0.jar présent. Tom Anderson a déjà fourni une bonne réponse pour exclure les «potins». – Ceki

Répondre

18

Votre problème ne reçoit pas deux copies de l'API SLF4J, il devient deux implémentations différentes SLF4J. Vous devez exclure Gossip, pas l'API. Cela signifie quelque chose comme:

<dependency> 
    <groupId>org.codehaus.gmaven.runtime</groupId> 
    <artifactId>gmaven-runtime-1.7</artifactId> 
    <version>1.3</version> 
    <exclusions> 
     <exclusion> 
     <groupId>org.sonatype.gossip</groupId> 
     <artifactId>gossip</artifactId> 
     </exclusion> 
    </exclusions> 
</dependency> 

La dépendance de Gossip est déclarée par gshell-io; heureusement, il n'a pas vraiment besoin de Gossip, il a juste besoin d'un SLF4J SLF4J, que vous fournissez sous forme de Logback.

+0

alors, vous voulez dire que je peux exclure la dépendance potins gratuitement, sans conséquences dramatiques?))) Bien, et s'il y a encore plus de dépendances qui, à leur tour, dépendent de slf4j, cela deviendra rapidement un cauchemar ((( – shabunc

+1

) La seule façon de rendre SLF4J heureux est soit de supprimer votre dépendance à Logback, ou exclure la dépendance de gshell-io sur Gossip, mais je ne peux pas promettre que cela n'aura pas de conséquences dramatiques J'espère que ce n'est pas le cas - ce serait très mauvais pour une bibliothèque d'avoir une dépendance directe sur une implémentation de journalisation –

+0

Le problème est dû à 2 fournisseurs différents ... potins jar a une implémentation slf4j à l'intérieur .. de sorte que vous devez soit supprimer logback ou potins de votre arbre de dépendance .. – Byter

1

Je suppose que vous devez jouer avec la portée des dépendances, voir: http://www.mojohaus.org/exec-maven-plugin/java-mojo.html

classpathScope - définit la portée du classpath transmis au plug-in. Définir pour compiler, tester, exécuter ou système en fonction de vos besoins.

+0

pouvez-vous, s'il vous plaît, être plus précis, je ne comprends toujours pas comment classpathScope aidera à résoudre ce problème. – shabunc

3

Tout ce que vous devez faire est d'ajouter quelque chose comme ça

compile "org.sonatype.gossip:gossip:1.0" { 
    exclude module:'slf4j-jcl' 
    exclude module:'slf4j-log4j12' 
} 
+0

Le problème est dû à la dépendance transitive du potin potins utilisé. Le code ci-dessus exclura la dépendance de l'implémentation sl4j des potins. – Byter

+2

"Quelque chose comme ça" signifie ici "l'équivalent Maven de ce code Gradle"! –

+0

@ TomAnderson ya ... désolé je n'ai pas mentionné que :) – Byter

Questions connexes