Frage

Was ist der Unterschied zwischen dependencyManagement und dependencies? Ich habe die Dokumentation zu Apache Maven Website gesehen. Es scheint, dass eine Abhängigkeit unter der dependencyManagement definiert sind, können ohne Angabe der Version in der untergeordneten Module verwendet werden.

Zum Beispiel:

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

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

Dann in dem Kind von Pro-Par, kann ich die junit verwenden:

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

Allerdings frage ich mich, ob es notwendig ist, junit in der Mutter pom zu definieren? Warum definiert sie nicht direkt in der benötigten Modul?

War es hilfreich?

Lösung

Abhängigkeitsmanagement ermöglicht die Konsolidierung und die Verwaltung von Abhängigkeiten Versionen zentralisieren ohne Zugabe von Abhängigkeiten, die von allen Kindern vererbt werden. Dies ist besonders nützlich, wenn Sie eine Reihe von Projekten (das heißt mehr als ein), dass erbt ein gemeinsamer Elternteil.

Ein weiterer äußerst wichtiger Anwendungsfall von dependencyManagement ist die Kontrolle der Versionen von Artefakten in transitive Abhängigkeiten verwendet. Das ist schwer, ohne ein Beispiel zu erklären. Glücklicherweise ist dies in der Dokumentation dargestellt.

Andere Tipps

Ich bin modern spät auf diese Frage, aber ich denke, es lohnt sich eine klarere Antwort als die akzeptierte ein (das ist richtig, aber nicht betonen, nicht die tatsächliche wichtige Rolle, die Sie brauchen, um sich ableiten).

In der übergeordneten POM, der Hauptunterschied zwischen dem <dependencies> und <dependencyManagement> ist diese:

angegeben Artefakte in der <dependencies> wird immer als eine Abhängigkeit des Kindes Modul (e) enthalten sein.

angegeben Artefakte in dem <dependencyManagement> , wird nur in dem Kind Modul aufgenommen werden, wenn sie auch angegeben wurden in dem <dependencies> des Kind Modul selbst. Warum ist es gut, fragen Sie? weil Sie die Version und / oder Umfang in den übergeordneten angeben, und Sie können sie aus verlassen, wenn die Abhängigkeiten in dem Kind POM angeben. Dies können Sie für Kind-Module verwenden Unified Versionen für Abhängigkeiten helfen, ohne die Version in jedem Kind Modul angeben.

Die Dokumentation auf der Maven-Website ist schrecklich. Was dependencyManagement tut, ist einfach Ihre Abhängigkeitsdefinitionen (Version, Ausschlüsse, usw.) bis zu dem übergeordneten pom, dann in den Kindern Poms bewegen müssen Sie nur noch die groupId und artifactId setzen. Das ist es (mit Ausnahme der Mutter pom Verkettungs und dergleichen, aber das ist auch nicht wirklich kompliziert - dependencyManagement siegt über Abhängigkeiten auf der übergeordneten Ebene - aber wenn Sie eine Frage zu diesem oder Importen haben, die Maven-Dokumentation ist ein wenig besser).

Nach all dem ‚a‘ zu lesen, ‚b‘, ‚c‘ Müll auf der Maven-Website und verwirrte, ich wieder schrieb ihr Beispiel. Also, wenn Sie zwei Projekte haben (proj1 und proj2), die eine gemeinsame Abhängigkeit (betaShared) teilen könnten Sie diese Abhängigkeit zu den Eltern pom nach oben bewegen. Während Sie gerade dabei sind, können Sie auch alle anderen Abhängigkeiten (alpha und charlie) nach oben, aber nur, wenn es sinnvoll für Ihr Projekt. Also für die Situation in den vorherigen Sätzen skizziert, hier ist die Lösung mit dependencyManagement in der Mutter 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>

Es ist wie du gesagt hat; dependencyManagementis verwendet, um alle Abhängigkeitsinformationen in eine gemeinsame POM-Datei zu ziehen, die Verweise in dem Kind POM-Datei zu vereinfachen.

Es wird nützlich, wenn Sie mehrere Attribute haben, dass Sie in unter mehreren Kindern Projekte neu eingeben wollen nicht.

Schließlich dependencyManagement verwendet werden kann, eine Standardversion eines Artefakts zu Verwendung über mehrere Projekte hinweg zu definieren.

Es gibt noch eine Sache, die nicht genug hervorgehoben ist, meiner Meinung nach, und das ist unerwü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 meinem Child A, Child B und Child C Module:

  • Implicilty von Kind Poms geerbt
  • Ein einzelner Ort verwalten
  • Keine Notwendigkeit, etwas in den Kindern Poms zu deklarieren
  • Ich kann immer noch redelcare und Überschreibung version 18.0 in einem Child B, wenn ich will.

Aber was ist, wenn ich am Ende nicht Guave in Child C benötigen, und weder in der Zukunft Child D und Child E Module?

Sie erben es noch, und dies unerwünscht ist! Das ist wie Java Gott Object Code Geruch, wo Sie einige nützliche Bits von einer Klasse erben, und ein tonn unerwünschte Dinge auch.

Dies ist, wo <dependencyManagement> ins Spiel kommt. Wenn Sie dies zu Ihrer Eltern pom hinzufügen, die alle Ihr Kind Module STOP es zu sehen . Und so sind Sie gezwungen in jedes einzelne Modul zu gehen, dass braucht es und erklären es wieder (Child A und Child B, ohne die Version obwohl).

Und, natürlich, Sie tun es nicht für Child C und damit Ihr Modul bleibt mager.

Es gibt ein paar Antworten umreißen Unterschiede zwischen <depedencies> und <dependencyManagement> Tags mit Maven.

jedoch einige Punkte erarbeitet unten in prägnanter Weise:

  1. <dependencyManagement> erlaubt es, alle Abhängigkeiten zu konsolidieren (at Kind pom Ebene verwendet wird) in den verschiedenen Modulen - Klarheit , zentrale Abhängigkeit Versionsmanagement
  2. <dependencyManagement> erlaubt auf einfache Weise aktualisieren / Herabstufung Abhängigkeiten basierend auf Notwendigkeit, diese Bedürfnisse in anderen Szenario bei jedem Kind pom Ebene ausgeübt werden - Konsistenz
  3. Abhängigkeiten in <dependencies>-Tag versehen werden immer importiert, während Abhängigkeiten bei <dependencyManagement> in Mutter pom bereitgestellt werden nur eingeführt werden, wenn das Kind pom entsprechenden Eintrag in seinem <dependencies>-Tag hat.

Wenn die Abhängigkeit in der Top-Level-pom des Elements dependencyManagement definiert wurde, hat das Kind Projekt nicht explizit die Version der Abhängigkeit aufzulisten. wenn das Kind Projekt eine Version definieren täte, würde es die Version in der obersten Ebene aufgelistet außer Kraft setzen POM dependencyManagement Abschnitt. Das heißt, die dependencyManagement Version nur das Kind verwendet, wenn keine Version direkt erklären.

Sorry, ich bin sehr spät zur Party.

Lassen Sie mich versuchen, den Unterschied mit mvn dependency:tree Befehl

zu erklären,

Betrachten Sie das folgende Beispiel

Eltern 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>

Child POM - App-Modul

(hat keine zusätzliche Abhängigkeit, so Abhängigkeiten leer zu verlassen)
 <dependencies>
</dependencies>

Auf mvn dependency:tree Befehl ausgeführt wird, erhalten wir folgendes 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 Guave als Abhängigkeit in jedem Modul aufgeführt ist (einschließlich der Mutter), während der Apache commons als Abhängigkeit aufgeführt ist nur in Datenmodul (auch nicht im Elternmodul)

In der übergeordneten POM, der Hauptunterschied zwischen den <dependencies> und <dependencyManagement> ist dies:

Artefakte im <dependencies> Abschnitt angegeben wird immer als eine Abhängigkeit des Kindes Modul enthalten sein (s).

Artefakte im Abschnitt angegeben wird, wird nur in dem Kind Modul aufgenommen werden, wenn sie auch im Abschnitt des Moduls Kind angegeben wurden selbst. Warum ist es gut, fragen Sie? weil Sie die Version und / oder Umfang in den übergeordneten angeben, und Sie können sie aus verlassen, wenn die Abhängigkeiten in dem Kind POM angeben. Dies können Sie für Kind-Module verwenden Unified Versionen für Abhängigkeiten helfen, ohne die Version in jedem Kind Modul angeben.

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

Der Unterschied zwischen den beiden ist am besten gebracht, was scheint eine notwendige und ausreichende Definition des dependencyManagement Element in Maven Webseite docs:

dependencyManagement

"Default Abhängigkeitsinformationen für Projekte, die erben von diesem. Die Abhängigkeiten in diesem Abschnitt werden nicht sofort gelöst werden. Stattdessen wird, wenn ein POM aus diesem abgeleitet eine Abhängigkeit von einem passenden groupId und artifactId, die Version und anderen Werten beschrieben erklärt aus diesem Abschnitt sind für diese Abhängigkeit verwendet, wenn sie nicht bereits angegeben wurden.“ [ https://maven.apache.org/ref/3.6 0,1 / maven-Modell / maven.html ]

Es sollte auf einer anderen Seite mit etwas mehr Informationen mitlesen werden:

„.. die minimale Menge von Informationen für eine Abhängigkeit Referenz gegen einen dependencyManagement Abschnitt passend ist eigentlich {groupId, artifactId, Typ, Klassifizierer}. In vielen Fällen beziehen sich diese Abhängigkeiten zu jar Artefakte ohne Klassifikator. Dies erlaubt uns, die Identität auf {groupId, artifactId} zu Kurzschrift, da der Standard für das Feld jar ist, und der Standard-Klassifikator ist null.“[ https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html ]

Damit sind alle Teilelemente (Umfang, Ausschlüsse usw.) eines Abhängigkeitselement - anders als groupId, artifactId, Typ, Klassifikator, nicht nur Version - verfügbar sind für Lockdown / default am Punkt (und also von dort weiter vererbt) Sie die Abhängigkeit innerhalb eines dependencyElement angeben. Wenn Sie eine Abhängigkeit mit der Art und Sichter Unterelement angegeben haben (siehe die erste zitierten Webseite alle Unterelemente zu überprüfen) als nicht jar und nicht jeweils null, dann würden Sie brauchen {groupId, artifactId, Klassifikator, Typ} auf Referenz (Vorsatz), die Abhängigkeit an einem beliebigen Punkt in einer Vererbungs mit Ursprung aus dem dependencyManagement Elemente. Else, {groupId, artifactId} würde genügen, wenn Sie nicht beabsichtigen, die Standardeinstellungen für Sichter und Art (Glas und null respectively) außer Kraft zu setzen. So Standard ist in dieser Definition ein gutes Stichwort; jedes Teilelement (e) (außer groupId, artifactId, Sichter und Art, natürlich) ausdrücklich zugewiesenen Wert (e) an der Stelle, eine Abhängigkeitsüberschreiben Sie die Standardeinstellung im dependencyManagement Elemente verweisen.

So kann jedes Abhängigkeitselement außerhalb von dependencyManagement, sei es als Referenz zu einem gewissen dependencyManagement Element oder als eigenständiges sofort behoben ist (das heißt an das lokale Repository installiert und verfügbar für CLASSPATHs).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top