wake-up-neo.com

Unterschiede zwischen DependencyManagement und Abhängigkeiten in Maven

Was ist der Unterschied zwischen dependencyManagement und dependencies? Ich habe die Dokumentation auf der Apache Maven-Website gesehen. Es scheint, dass eine unter dependencyManagement definierte Abhängigkeit in ihren untergeordneten Modulen verwendet werden kann, ohne die Version anzugeben.

Zum Beispiel:

Ein übergeordnetes Projekt (Pro-par) definiert eine Abhängigkeit unter dem dependencyManagement:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8</version>
    </dependency>
 </dependencies>
</dependencyManagement>

Dann kann ich in dem Kind von Pro-par das junit benutzen:

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
 </dependencies>

Ich frage mich jedoch, ob es notwendig ist, junit im übergeordneten pom zu definieren. Warum nicht direkt im benötigten Modul definieren?

648
hguser

Abhängigkeitsverwaltung ermöglicht die Konsolidierung und Zentralisierung der Verwaltung von Abhängigkeitsversionen, ohne dass Abhängigkeiten hinzugefügt werden müssen, die von allen untergeordneten Elementen geerbt werden. Dies ist besonders nützlich, wenn Sie eine Reihe von Projekten (d. H. Mehr als eines) haben, das ein gemeinsames übergeordnetes Element erbt.

Ein weiterer äußerst wichtiger Anwendungsfall von dependencyManagement ist die Steuerung von Versionen von Artefakten, die in transitiven Abhängigkeiten verwendet werden. Dies ist ohne ein Beispiel schwer zu erklären. Zum Glück ist dies in der Dokumentation dargestellt.

414
Pascal Thivent

Ich bin auf diese Frage ziemlich spät dran, aber ich denke, dass es eine klarere Antwort wert ist als die akzeptierte (was korrekt ist, aber nicht den wirklich wichtigen Teil betont, den Sie selbst ableiten müssen).

Im übergeordneten POM ist der Hauptunterschied zwischen <dependencies> und <dependencyManagement>:

Die im Abschnitt <dependencies> angegebenen Artefakte werden IMMER als Abhängigkeit von den untergeordneten Modulen einbezogen.

Artefakte, die im Abschnitt <dependencyManagement> angegeben wurden, werden nur in das untergeordnete Modul aufgenommen, wenn sie auch im Abschnitt <dependencies> des untergeordneten Moduls angegeben wurden selbst. Warum ist es gut, fragst du? da Sie die Version und/oder den Bereich im übergeordneten POM angeben und diese bei der Angabe der Abhängigkeiten im untergeordneten POM weglassen können. Dies kann Ihnen helfen, einheitliche Versionen für Abhängigkeiten für untergeordnete Module zu verwenden, ohne die Version in jedem untergeordneten Modul anzugeben.

635
dcoder

Das Dokumentation auf der Maven-Site ist schrecklich. Mit dependencyManagement verschieben Sie einfach Ihre Abhängigkeitsdefinitionen (Version, Ausschlüsse usw.) auf den übergeordneten POM. In den untergeordneten POMs müssen Sie dann nur die groupId und die artifactId einfügen. Das ist alles (mit Ausnahme der Verkettung von übergeordneten POMs und dergleichen, aber das ist auch nicht wirklich kompliziert - dependencyManagement setzt sich für Abhängigkeiten auf übergeordneter Ebene ein - aber wenn Sie Fragen dazu oder zum Importieren haben, ist die Maven-Dokumentation etwas besser).

Nachdem ich den gesamten "a", "b", "c" -Müll auf der Maven-Site gelesen hatte und mich verwirrt hatte, schrieb ich ihr Beispiel neu. Wenn Sie also zwei Projekte (proj1 und proj2) haben, die eine gemeinsame Abhängigkeit haben (betaShared), können Sie diese Abhängigkeit auf das übergeordnete pom verschieben. Während Sie gerade dabei sind, können Sie auch andere Abhängigkeiten (Alpha und Charlie) nachrücken, aber nur, wenn dies für Ihr Projekt sinnvoll ist. Für die in den vorhergehenden Sätzen beschriebene Situation ist hier die Lösung mit DependencyManagement im übergeordneten POM:

<!-- ParentProj pom -->
<project>
  <dependencyManagement>
    <dependencies>
      <dependency> <!-- not much benefit defining alpha here, as we only use in 1 child, so optional -->
        <groupId>alpha</groupId>
        <artifactId>alpha</artifactId>
        <version>1.0</version>
        <exclusions>
          <exclusion>
            <groupId>zebra</groupId>
            <artifactId>zebra</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      <dependency>
        <groupId>charlie</groupId> <!-- not much benefit defining charlie here, so optional -->
        <artifactId>charlie</artifactId>
        <version>1.0</version>
        <type>war</type>
        <scope>runtime</scope>
      </dependency>
      <dependency> <!-- defining betaShared here makes a lot of sense -->
        <groupId>betaShared</groupId>
        <artifactId>betaShared</artifactId>
        <version>1.0</version>
        <type>bar</type>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

<!-- Child Proj1 pom -->
<project>
  <dependencies>
    <dependency>
      <groupId>alpha</groupId>
      <artifactId>alpha</artifactId>  <!-- jar type IS DEFAULT, so no need to specify in child projects -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId>
      <artifactId>betaShared</artifactId>
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>

<!-- Child Proj2 -->
<project>
  <dependencies>
    <dependency>
      <groupId>charlie</groupId>
      <artifactId>charlie</artifactId>
      <type>war</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId> 
      <artifactId>betaShared</artifactId> 
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>
45
MattC

Es ist wie du gesagt hast; dependencyManagement wird verwendet, um alle Abhängigkeitsinformationen in eine gemeinsame POM-Datei zu ziehen, wodurch die Referenzen in der untergeordneten POM-Datei vereinfacht werden.

Dies ist nützlich, wenn Sie mehrere Attribute haben, die Sie nicht unter mehreren untergeordneten Projekten erneut eingeben möchten.

Schließlich kann mit dependencyManagement eine Standardversion eines Artefakts definiert werden, die projektübergreifend verwendet werden soll.

44
Pran

Es gibt noch eine Sache, die meiner Meinung nach nicht genug hervorgehoben ist, und das ist nerwünschte Vererbung.

Hier ist ein inkrementelles Beispiel:

Ich erkläre in meinem parent pom:

<dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>
</dependencies>

boom! Ich habe es in meinen Child A, Child B und Child C Modulen:

  • Implicilty von Kind Poms geerbt
  • Ein einziger Ort zum Verwalten
  • Keine Notwendigkeit, etwas in Kinderpoms neu zu deklarieren
  • Ich kann mich immer noch erneut darum kümmern und version 18.0 in einem Child B überschreiben, wenn ich möchte.

Aber was ist, wenn ich in Child C und in den zukünftigen Child D und Child E Modulen keine Guave benötige?

Sie werden es immer noch erben und das ist unerwünscht! Dies ist genau wie Java God Object-Code-Geruch, bei dem Sie einige nützliche Bits von einer Klasse und eine Menge unerwünschter Dinge als erben Gut.

Hier kommt <dependencyManagement> ins Spiel. Wenn Sie dies zu Ihrem übergeordneten POM hinzufügen, werden alle Ihre untergeordneten Module nicht mehr zu sehen. Und so müssen Sie gezwungen in jedes einzelne Modul gehen, das es benötigt, und es erneut deklarieren (Child A und Child B, jedoch ohne die Version).

Und offensichtlich tun Sie es nicht für Child C, und daher bleibt Ihr Modul schlank.

33
Andrejs

Es gibt einige Antworten, die die Unterschiede zwischen den Tags <depedencies> und <dependencyManagement> mit maven beschreiben.

Im Folgenden werden jedoch einige Punkte kurz erläutert:

  1. <dependencyManagement> ermöglicht die Konsolidierung aller Abhängigkeiten (die auf untergeordneter POM-Ebene verwendet werden), die in verschiedenen Modulen verwendet werden - Übersichtlichkeit, zentrales Versionsmanagement für Abhängigkeiten
  2. <dependencyManagement> ermöglicht ein einfaches Upgrade/Downgrade von Abhängigkeiten je nach Bedarf. In anderen Szenarien muss dies auf jeder untergeordneten POM-Ebene durchgeführt werden - Konsistenz
  3. abhängigkeiten, die im Tag <dependencies> bereitgestellt werden, werden immer importiert, während Abhängigkeiten, die im übergeordneten POM unter <dependencyManagement> bereitgestellt werden, nur dann importiert werden, wenn das untergeordnete POM über einen entsprechenden Eintrag im Tag <dependencies> verfügt.
15
Anamika

Wenn die Abhängigkeit im dependencyManagement-Element der obersten Ebene von pom definiert wurde, musste das untergeordnete Projekt die Version der Abhängigkeit nicht explizit auflisten. Wenn das untergeordnete Projekt eine Version definiert hat, wird die im Abschnitt "DependencyManagement" des POM auf oberster Ebene aufgeführte Version überschrieben. Das heißt, die dependencyManagement-Version wird nur verwendet, wenn das untergeordnete Element eine Version nicht direkt deklariert.

9
Mustafa Güven

Tut mir leid, dass ich zu spät zur Party komme.

Lassen Sie mich versuchen, den Unterschied mit dem Befehl mvn dependency:tree zu erklären

Betrachten Sie das folgende Beispiel

Übergeordnetes POM - Mein Projekt

<modules>
    <module>app</module>
    <module>data</module>
</modules>

<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.Apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Child POM - Datenmodul

<dependencies>
    <dependency>
        <groupId>org.Apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
</dependencies>

ntergeordnetes POM - App - Modul (hat keine zusätzliche Abhängigkeit, lässt also die Abhängigkeiten leer

 <dependencies>
</dependencies>

Wenn Sie den Befehl mvn dependency:tree ausführen, erhalten Sie das folgende Ergebnis

Scanning for projects...
------------------------------------------------------------------------
Reactor Build Order:

MyProject
app
data

------------------------------------------------------------------------
Building MyProject 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ MyProject ---
com.iamvickyav:MyProject:pom:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building app 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ app ---
com.iamvickyav:app:jar:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building data 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ data ---
com.iamvickyav:data:jar:1.0-SNAPSHOT
+- org.Apache.commons:commons-lang3:jar:3.9:compile
\- com.google.guava:guava:jar:19.0:compile

Google guava wird in jedem Modul (einschließlich des übergeordneten Moduls) als Abhängigkeit aufgeführt, während Apache commons nur im Datenmodul (nicht einmal im übergeordneten Modul) als Abhängigkeit aufgeführt wird.

6
IamVickyAV

Im übergeordneten POM ist der Hauptunterschied zwischen <dependencies> und <dependencyManagement> wie folgt:

Die im Abschnitt <dependencies> angegebenen Artefakte werden IMMER als Abhängigkeit der untergeordneten Module einbezogen.

In diesem Abschnitt angegebene Artefakte werden nur dann in das untergeordnete Modul aufgenommen, wenn sie auch im Abschnitt des untergeordneten Moduls selbst angegeben wurden. Warum ist es gut, fragst du? da Sie die Version und/oder den Bereich im übergeordneten POM angeben und diese bei der Angabe der Abhängigkeiten im untergeordneten POM weglassen können. Dies kann Ihnen helfen, einheitliche Versionen für Abhängigkeiten für untergeordnete Module zu verwenden, ohne die Version in jedem untergeordneten Modul anzugeben.

3
Yaver

Der Unterschied zwischen den beiden wird am besten in der notwendigen und ausreichenden Definition des dependencyManagement-Elements hervorgehoben, das in den Dokumenten der Maven-Website verfügbar ist:

dependencyManagement

"Standardabhängigkeitsinformationen für Projekte, die von diesem erben. Die Abhängigkeiten in diesem Abschnitt werden nicht sofort aufgelöst. Wenn ein davon abgeleiteter POM stattdessen eine Abhängigkeit deklariert, die durch eine übereinstimmende groupId und artifactId, die Version und andere Werte aus diesem Abschnitt beschrieben wird werden für diese Abhängigkeit verwendet, wenn sie nicht bereits angegeben wurden. " [ https://maven.Apache.org/ref/3.6.1/maven-model/maven.html ]

Es sollte zusammen mit einigen weiteren Informationen auf einer anderen Seite gelesen werden:

"..Der minimale Satz von Informationen zum Abgleichen eines Abhängigkeitsverweises mit einem Abhängigkeitsverwaltungsabschnitt ist tatsächlich {groupId, artifactId, type, classifier}. In vielen Fällen beziehen sich diese Abhängigkeiten auf Jar-Artefakte ohne Klassifikator. Dies ermöglicht es uns, die auf {groupId, artifactId} festgelegte Identität zu verkürzen, da der Standardwert für das Typfeld jar und der Standardklassifizierer null ist. “[ https://maven.Apache.org/guides/ Einführung/Einführung-in-Abhängigkeitsmechanismus.html ]

Daher sind alle Unterelemente (Gültigkeitsbereich, Ausschlüsse usw.) eines Abhängigkeitselements - außer groupId, artifactId, type, classifier und nicht nur version - zum Zeitpunkt der Sperrung/Standardeinstellung verfügbar (und werden daher von übernommen) dort weiter) geben Sie die Abhängigkeit innerhalb eines dependencyElement an. Wenn Sie eine Abhängigkeit mit den Unterelementen type und classifier angegeben hätten (auf der zuerst genannten Webseite werden alle Unterelemente überprüft), die nicht jar bzw. nicht null ist, benötigen Sie {groupId, artifactId, classifier, type}. Verweisen (Auflösen) dieser Abhängigkeit an einem beliebigen Punkt in einer Vererbung, die vom dependencyManagement-Element stammt. Andernfalls würde {groupId, artifactId} ausreichen, wenn Sie nicht beabsichtigen, die Standardwerte für classifier und type (jar bzw. null) zu überschreiben. Standard ist also ein gutes Schlüsselwort in dieser Definition. Alle Unterelemente (außer groupId, artifactId, classifier und type), die an dem Punkt, an dem Sie auf eine Abhängigkeit verweisen, explizit zugewiesen wurden, überschreiben die Standardwerte im dependencyManagement-Element.

Daher wird jedes Abhängigkeitselement außerhalb von dependencyManagement sofort aufgelöst (d. H. Im lokalen Repository installiert und für Klassenpfade verfügbar), unabhängig davon, ob es auf ein Abhängigkeitselement verweist oder als eigenständiges Element.

1
rps

In Eclipse gibt es eine weitere Funktion in dependencyManagement. Wenn dependencies ohne verwendet wird, werden die nicht gefundenen Abhängigkeiten in der pom-Datei bemerkt. Wenn dependencyManagement verwendet wird, bleiben die ungelösten Abhängigkeiten in der pom-Datei unbemerkt und Fehler werden nur in den Java -Dateien angezeigt. (Importe und so ...)

1
Gangnus