Disons que j'ai quatre projets:
Dans ce scénario, si j'exécute le projet A, Maven résoudra correctement la dépendance en D. Si je comprends bien, Maven prend toujours la dépendance avec le chemin le plus court. Puisque D est une dépendance directe de A, il sera plutôt utilisé, le D qui est spécifié dans B.
Mais assumons maintenant cette structure:
Dans ce cas, les chemins de résolution de D ont la même profondeur. Ce qui se passe, c'est que Maven aura un conflit. Je sais qu'il est possible de dire à Maven qu'il devrait exclure les dépendances. Mais ma question est de savoir comment résoudre ce genre de problèmes. Je veux dire que dans une application réelle, vous avez beaucoup de dépendances et peut-être aussi beaucoup de conflits.
La meilleure pratique est-elle vraiment d'exclure des éléments ou existe-t-il d'autres solutions possibles? Je trouve cela très difficile à gérer lorsque j'obtiens soudain une exception ClassNotFound car certaines versions ont changé, ce qui a amené Maven à prendre une dépendance différente. En effet, le fait de savoir ce fait permet de deviner un peu plus facilement que le problème est un conflit de dépendance.
J'utilise maven 2.1-SNAPSHOT.
La manière la plus simple de résoudre des situations comme celle-ci consiste à inclure un <dependencyManagement>
section dans le pom racine de votre projet, où vous spécifiez quelle version de quelle bibliothèque sera utilisée.
MODIFIER:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
</dependencyManagement>
Quelle que soit la version de la bibliothèque foo: bar demandée par une dépendance, la version 1.2.3 sera toujours utilisée pour ce projet et tous les sous-projets.
Référence:
Maven peut gérer les deux situations sans aucun conflit. Des conflits existent lorsque deux versions d'une dépendance transitive sont requises. Le ClassNotFoundException
que vous décrivez résulte de l'application (ou d'une dépendance) qui tente d'utiliser une classe non disponible dans la version de la dépendance en conflit qui est réellement utilisée. Il existe plusieurs façons de résoudre le problème.
<dependencyManagement>
section du POM<exclusion>
Ce n'est fondamentalement pas un problème maven, mais un problème Java. Si le projet B et le projet C ont besoin de deux versions incompatibles du projet D, vous ne pouvez pas les utiliser tous les deux dans le projet A.
La manière Maven de résoudre des conflits comme ceux-ci est malheureusement, comme vous le savez déjà, de choisir ceux à exclure.
En utilisant mvn dependency:analyze
et mvn dependency:tree
aide à trouver les conflits que vous avez.
Vous pouvez appliquer des dépendances cohérentes dans l'ensemble du projet avec la règle Convergence des dépendances .
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<DependencyConvergence/>
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>
Une stratégie possible consiste à spécifier pour le projet principal, quelle version de D utiliser (la plus récente f.g.). Cependant, si la bibliothèque D n'est pas rétrocompatible, vous avez un problème comme indiqué par kukudas - il est impossible d'utiliser les deux bibliothèques dans votre projet.
Dans une telle situation, il peut être nécessaire d'utiliser B ou C dans une ancienne version, de sorte que les deux dépendent des versions compatibles de D.