2017-02-09 1 views
4

meiner Meinung nach das Maven-Abhängigkeits-Plugin ist falsch bei der Berechnung der Abhängigkeitsliste.maven dependency plugin ignoriert Abhängigkeitsversionen?

Angenommen, diese drei Projekte:

Base1:

<?xml version="1.0" encoding="UTF-8"?>                                
<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>mygroup</groupId> 
    <artifactId>base1</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <dependencies> 
     <dependency> 
     <groupId>commons-lang</groupId> 
     <artifactId>commons-lang</artifactId> 
     <version>2.3</version> 
     </dependency> 
    </dependencies> 
</project> 

base2:

<?xml version="1.0" encoding="UTF-8"?>                                
<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>mygroup</groupId> 
    <artifactId>base2</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <dependencies> 
     <dependency> 
     <groupId>commons-lang</groupId> 
     <artifactId>commons-lang</artifactId> 
     <version>2.6</version> 
     </dependency> 
    </dependencies> 
</project> 

kombiniert:

<?xml version="1.0" encoding="UTF-8"?>                                
<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>mygroup</groupId> 
    <artifactId>combined</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <dependencies> 
     <dependency> 
     <groupId>mygroup</groupId> 
     <artifactId>base1</artifactId> 
     <version>1.0-SNAPSHOT</version> 
     </dependency> 
     <dependency> 
     <groupId>mygroup</groupId> 
     <artifactId>base2</artifactId> 
     <version>1.0-SNAPSHOT</version> 
     </dependency> 
    </dependencies> 
</project> 

Sowohl Base1 und base2 hängen von commons-lang , aber jeder auf einer anderen Ausführung! kombiniert hängt von beiden ab, base1 und base2.

Beim Aufruf von mvn dependency:list auf kombiniert, würde ich erwarten, base1, base2 und commons-lang in den Versionen 2.3 und 2.6 zu sehen, da beide verwendet werden. jedoch die tatsächliche Ausgabe ist:

[INFO] The following files have been resolved: 
[INFO] commons-lang:commons-lang:jar:2.3:compile 
[INFO] mygroup:base1:jar:1.0-SNAPSHOT:compile 
[INFO] mygroup:base2:jar:1.0-SNAPSHOT:compile 

Es ist nicht einmal mit der Common-lang mit der höchsten Versionsnummer, sondern nur die, die es zuerst findet.

Wie kann ich dies vermeiden? Ich brauche alle Abhängigkeiten.

+0

Das Beste für Sie wäre, den Code zu ändern, der eine Abhängigkeit von commons-lang erfordert: 2.3. Sorry ... – otonglet

+0

@otonglet Wenn base1 und base2 Module von Drittanbietern sind, kann ich das nicht tun. – radlan

+0

@radlan sind Sie zufällig verwirrend 'mvn Abhängigkeit: Liste' mit [' mvn Abhängigkeit: Baum'] (https://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html)? – nullpointer

Antwort

3

Nach dieser official documentation (mit dem entsprechenden Teil fett markiert):

Abhängigkeitsvermittlung - bestimmt, welche Version einer Abhängigkeit verwendet wird, wenn mehrere Versionen eines Artefakts auftreten. Gegenwärtig unterstützt Maven 2.0 nur die "nächste Definition", was bedeutet, dass es die Version der nächsten Abhängigkeit zu Ihrem Projekt in der Baumstruktur der Abhängigkeiten verwendet. Sie können eine Version immer garantieren, indem Sie sie explizit im POM Ihres Projekts deklarieren. Beachten Sie, dass, wenn zwei Abhängigkeitsversionen in der Abhängigkeitsbaumstruktur die gleiche Tiefe haben, bis Maven 2.0.8 nicht definiert wurde, welche gewonnen würde, aber seit Maven 2.0.9 zählt die Reihenfolge in der Deklaration: Die erste Deklaration gewinnt .

Deshalb wählt Maven Version 2.3, weil es zuerst in der Abhängigkeitsauflösung auftritt.Beachten Sie, dass bei Ausführung von mvn dependency:tree auf dem Modul combined angezeigt wird, welche Version verwendet wurde und welche Version weggelassen wurde.

Die beste Lösung ist explizit die Version, die Sie im combined Artefakt wollen holen, durch die Abhängigkeit in seiner POM erklärt, so dass Maven begünstigt es gegenüber anderen Versionen:

<?xml version="1.0" encoding="UTF-8"?> 
<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>mygroup</groupId> 
    <artifactId>combined</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <dependencies> 
    <dependency> 
     <groupId>mygroup</groupId> 
     <artifactId>base1</artifactId> 
     <version>1.0-SNAPSHOT</version> 
    </dependency> 
    <dependency> 
     <groupId>mygroup</groupId> 
     <artifactId>base2</artifactId> 
     <version>1.0-SNAPSHOT</version> 
    </dependency> 
    <dependency> <!-- This will override the versions in base1 and base2 --> 
     <groupId>commons-lang</groupId> 
     <artifactId>commons-lang</artifactId> 
     <version>2.6</version> 
    </dependency> 
    </dependencies> 

Beachten Sie, dass Maven Sie können keine zwei Versionen auswählen, da in diesem Fall zwei Definitionen für die gleichen Klassen im Klassenpfad Ihres Projekts vorhanden sind, was zur Laufzeit zu unerwarteten Problemen führen kann.

+0

Eigentlich scheint das die einzige Lösung zu sein. Es ist nicht genau das, was ich will, da zum Beispiel base1 und base2 ausführbare Anwendungen sind, deren Klassenpfad während der Erstellungszeit generiert wird und kombiniert nur ein _container_ für die Anwendungen ist, die alle Abhängigkeiten zusammenstellen, base2 wird nicht ausführbar sein, da die Abhängigkeit von seinem Klassenpfad ist nicht in den zusammengesetzten Abhängigkeiten enthalten. Es scheint jedoch, dass ich hier stecken bleibe und Ihr Vorschlag wäre die beste mögliche Lösung. – radlan

+0

@radlan Ich vermisse etwas, aber basierend auf Ihrer Beschreibung, wo Sie sagen "base1 und base2 sind ausführbare Anwendungen", scheint es, dass Sie den Build in zwei separate Builds trennen sollten, wobei Build # 1 base1 und build # 2 base2 erstellt. und in diesem Fall verwendet jeder Build seine eigene separate Version der Abhängigkeit. Wie auch immer, hier ist ein Beitrag, der verwandt scheint: http://stackoverflow.com/questions/24962607/multiple-versions-of-the-same-dependency-in-maven. Ich habe es zufällig auch beantwortet. Möglicherweise können Sie in diesem Fall Maven-Profile verwenden. Jedes Profil kann seine eigene Abhängigkeit angeben. – manouti

+0

base1 und base2 haben separate Builds. Aber es gibt auch einen anderen Build, der diese anderen Builds bündelt, um die Bereitstellung des gesamten Pakets zu erleichtern. – radlan

1

Maven scannt den Pom von oben nach unten und verwendet die erste Version, auf die er trifft.

Angenommen, Sie benötigen beide Versionen von commons-lang, können Sie diese beiden Versionen in Ihr Projekt einfügen und maven verwenden, um sie in Ihr jar zu packen.

Doch wie könnte der Compiler wissen, ob ein Aufruf an StringUtils.isEmpty() die Version 2.3 oder 2.6 aufruft?

Same discussion here.

Verwandte Themen