Angenommen, ich habe vier Projekte:
- Projekt A (abhängig von B und D)
- Projekt B (hat eine Abhängigkeit von D)
- Projekt C (abhängig von D)
- Projekt D.
Wenn ich in diesem Szenario Projekt A ausführe, löst Maven die Abhängigkeit von D korrekt auf. Wenn ich dies richtig verstehe, nimmt Maven die Abhängigkeit immer mit dem kürzesten Pfad. Da D eine direkte Abhängigkeit von A ist, wird eher das D verwendet, das in B angegeben ist.
Nehmen wir nun diese Struktur an:
- Projekt A (abhängig von B und C)
- Projekt B (hat eine Abhängigkeit von D)
- Projekt C (abhängig von D)
- Projekt D.
In diesem Fall haben die Pfade zum Auflösen von D die gleiche Tiefe. Was passiert ist, dass Maven einen Konflikt haben wird. Ich weiß, dass es möglich ist, Maven zu sagen, dass er Abhängigkeiten ausschließen sollte. Aber meine Frage ist, wie man solche Probleme angeht. Ich meine, in einer realen Anwendung haben Sie viele Abhängigkeiten und möglicherweise auch viele Konflikte.
Ist die Best-Practice-Lösung wirklich, um Dinge auszuschließen, oder gibt es andere mögliche Lösungen dafür? Ich finde es sehr schwierig, damit umzugehen, wenn ich plötzlich eine ClassNotFound-Ausnahme bekomme, weil sich einige Versionen geändert haben, was dazu führte, dass Maven eine andere Abhängigkeit annahm. Wenn Sie diese Tatsache kennen, können Sie natürlich leichter erraten, dass es sich bei dem Problem um einen Abhängigkeitskonflikt handelt.
Ich benutze Maven 2.1-SNAPSHOT.
Antworten:
Die Maven-Methode zum Lösen solcher Situationen besteht darin, einen
<dependencyManagement>
Abschnitt in das Stammfenster Ihres Projekts aufzunehmen, in dem Sie angeben, welche Version welcher Bibliothek verwendet werden soll.BEARBEITEN:
<dependencyManagement> <dependencies> <dependency> <groupId>foo</groupId> <artifactId>bar</artifactId> <version>1.2.3</version> </dependency> </dependencies> </dependencyManagement>
Unabhängig davon, welche Version der Bibliothek foo: bar von einer Abhängigkeit angefordert wird, wird für dieses Projekt und alle Unterprojekte immer Version 1.2.3 verwendet.
Referenz:
quelle
dependencyManagement
gelten die in angegebenen Versionsnummern für transitive Abhängigkeiten und Projektabhängigkeiten ohne explizite Version. Projektabhängigkeiten mit einer expliziten Version überschreiben jedoch die Version imdependencyManagement
Abschnitt.Maven kann beide Situationen ohne Konflikte bewältigen. Konflikte bestehen, wenn zwei Versionen einer transitiven Abhängigkeit erforderlich sind. Die
ClassNotFoundException
Sie beschreiben , ergibt sich aus der App (oder einer Abhängigkeit) versucht , eine Klasse zu verwenden , nicht verfügbar in der Version der Konflikt Abhängigkeit, wird tatsächlich verwendet wird . Es gibt mehrere Möglichkeiten, das Problem zu beheben.<dependencyManagement>
Abschnitt des POM an, welche Version der Konfliktabhängigkeit transitive Abhängigkeiten verwenden sollen<exclusion>
quelle
Dies ist im Grunde kein Maven-Problem, sondern ein Java-Problem. Wenn Projekt B und Projekt C zwei inkompatible Versionen von Projekt D benötigen, können Sie beide nicht in Projekt A verwenden.
Wie Sie bereits wissen, besteht die Maven-Methode zur Lösung solcher Konflikte leider darin, auszuwählen, welche ausgeschlossen werden sollen.
Verwenden
mvn dependency:analyze
undmvn dependency:tree
hilft bei der Suche nach Konflikten.quelle
Mit der Regel Abhängigkeitskonvergenz können Sie konsistente Abhängigkeiten im gesamten Projekt erzwingen .
<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>
quelle
Eine mögliche Strategie besteht darin, für das Hauptprojekt anzugeben, welche Version von D verwendet werden soll (die neueste fg). Wenn Bibliothek D jedoch nicht abwärtskompatibel ist, haben Sie ein Problem, wie von kukudas angegeben - es ist unmöglich, beide Bibliotheken in Ihrem Projekt zu verwenden.
In einer solchen Situation kann es erforderlich sein, in älteren Versionen entweder B oder C zu verwenden, sodass beide von kompatiblen Versionen von D abhängen.
quelle