Domanda

Qual è la differenza tra dependencyManagement e dependencies? Ho visto la documentazione al sito web Apache Maven. Sembra che una dipendenza definito sotto il dependencyManagement può essere utilizzato nei suoi moduli bambino senza specificare la versione.

Ad esempio:

Un progetto principale (Pro-par) definisce una dipendenza sotto il dependencyManagement:

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

Poi nel bambino di Pro-par, posso usare il JUnit:

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

Tuttavia, mi chiedo se è necessario definire JUnit in POM genitore? Perché non definirlo direttamente nel modulo necessario?

È stato utile?

Soluzione

Dipendenza Gestione permette di consolidare e centralizzare la gestione di versioni di dipendenza senza l'aggiunta di dipendenze che sono ereditati da tutti i bambini. Ciò è particolarmente utile quando si ha una serie di progetti (vale a dire più di uno) che eredita un genitore comune.

Un altro importantissimo caso d'uso del dependencyManagement è il controllo delle versioni di manufatti utilizzati nelle dipendenze transitive. Questo è difficile da spiegare senza un esempio. Per fortuna, questo è illustrato nella documentazione.

Altri suggerimenti

Sono alla moda in ritardo a questa domanda, ma penso che valga la pena di una risposta più chiara di quello accettato (che è corretto, ma non enfatizza la parte importante reale, che è necessario dedurre da soli).

Nel POM genitore, la principale differenza tra il <dependencies> e <dependencyManagement> è questo:

Gli artefatti specificati nel <dependencies> sarà sempre incluso come dipendenza del modulo di bambino (s).

Gli artefatti specificati nel <dependencyManagement>, sarà incluso solo nel modulo bambino se fossero anche specificati nel <dependencies> del modulo bambino stesso. Perché è buono vi chiederete? perché si specifica la versione e / o la portata nel genitore, e li si può lasciare fuori quando si specificano le dipendenze nel POM bambino. Questo può aiutare a utilizzare versioni unificate per le dipendenze per i moduli di bambino, senza specificare la versione in ogni modulo del bambino.

Il documentazione sul sito Maven è orribile. Ciò che dependencyManagement fa è semplicemente spostare le definizioni di dipendenza (versione, esclusioni, ecc) fino alla POM genitore, poi nei pon bambino devi solo mettere la groupId e artifactId. Questo è tutto (tranne che per il genitore pom concatenamento e simili, ma che non è davvero complicato sia - dependencyManagement vince sui dipendenze a livello di genitore - ma se hanno una domanda su questo o importa, la documentazione Maven è un po 'meglio).

Dopo aver letto tutte la 'a', 'b', 'c' spazzatura sul sito Maven e confondersi, ho ri-scritto il loro esempio. Quindi, se avete avuto 2 progetti (proj1 e Proj2) che condividono una dipendenza comune (betaShared) è possibile spostare che la dipendenza fino al pom genitore. Mentre si è in esso, è anche possibile spostare eventuali altre dipendenze (alfa e Charlie), ma solo se ha un senso per il vostro progetto. Così, per la situazione descritta nelle frasi precedenti, ecco la soluzione con dependencyManagement nel pom genitore:

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

E 'come hai detto; dependencyManagementis utilizzato per estrarre tutte le informazioni sulle dipendenze in un file POM comuni, semplificando i riferimenti nel file secondario POM.

diventa utile quando si hanno più attributi che non si desidera digitare nuovamente in meno di progetti più figli.

Infine, dependencyManagement può essere utilizzato per definire una versione standard di un manufatto ad uso su più progetti.

C'è ancora una cosa che non viene evidenziato a sufficienza, a mio parere, e che è eredità indesiderate .

Ecco un esempio incrementale:

dichiaro nella mia parent pom:

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

boom! Ce l'ho nel mio Child A, moduli Child B e Child C:

  • Implicilty ereditato da pon bambino
  • Un luogo unico per la gestione
  • Non c'è bisogno di nulla in ridichiarare pon bambino
  • posso ancora redelcare e override per version 18.0 in un Child B se voglio.

Ma cosa succede se io alla fine non hanno bisogno guava in Child C, e né in futuro Child D e moduli Child E?

saranno ancora ereditare esso e questo è indesiderata! Questo è proprio come il codice oggetto Java Dio odore, dove si eredita alcuni bit utili da una classe, e un tonn di roba indesiderata pure.

E 'qui che entra in gioco <dependencyManagement>. Quando si aggiunge questo al vostro pom genitore, tutti i moduli bambino STOP vederlo . E così si è costretto per entrare in ogni singolo modulo che ha bisogno di essa e dichiarare di nuovo (Child A e Child B, senza la versione però).

E, ovviamente, non lo fai per Child C, e, quindi, il modulo rimane magra.

Ci sono alcune risposte delineano differenze tra <depedencies> e <dependencyManagement> tag con Maven.

Tuttavia, alcuni punti elaborata sotto in modo conciso:

  1. <dependencyManagement> permette di consolidare tutte le dipendenze (utilizzato a livello bambino pom) utilizzati in diversi moduli - chiarezza , dipendenza centrale di gestione delle versioni
  2. <dependencyManagement> consente di aggiornare facilmente le dipendenze / downgrade in base alle esigenze, in altro scenario questo deve essere esercitato a tutti i livelli figlio pom - coerenza
  3. dipendenze fornite nel tag <dependencies> è sempre importato, mentre le dipendenze offerti da <dependencyManagement> in POM genitore verranno importati solo se pom bambino ha rispettiva voce nel suo tag <dependencies>.

Se la dipendenza è stato definito nel elemento dependencyManagement del pom-alto livello, il progetto figlio non doveva elencare esplicitamente la versione della dipendenza. se il progetto figlio ha fatto definire una versione, sarebbe ignorare la versione elencata nella top-level sezione dependencyManagement di POM. Cioè, la versione dependencyManagement è solo utilizzato quando il bambino non dichiara direttamente una versione.

mi dispiace molto in ritardo alla festa.

Vorrei cercare di spiegare la differenza utilizzando il comando mvn dependency:tree

Si consideri l'esempio di seguito

Parent POM - My Project

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

Bambino POM - modulo dati

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

Bambino POM - Modulo app (ha alcuna dipendenza in più, in modo da lasciare le dipendenze svuotare)

 <dependencies>
</dependencies>

Il comando mvn dependency:tree esecuzione, otteniamo risultato seguente

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 è elencato come la dipendenza in ogni modulo (compreso madre), mentre il Apache Commons è elencato come la dipendenza solo nel modulo dati (nemmeno nel modulo genitore)

Nel POM genitore, la differenza principale tra la <dependencies> e <dependencyManagement> è questa:

Gli artefatti specificati nella sezione <dependencies> sarà sempre incluso come dipendenza del modulo di bambino (s).

Gli artefatti specificati nella sezione, sarà incluso solo nel modulo bambino se fossero anche specificati nella sezione del modulo bambino stesso. Perché è buono vi chiederete? perché si specifica la versione e / o la portata nel genitore, e li si può lasciare fuori quando si specificano le dipendenze nel POM bambino. Questo può aiutare a utilizzare versioni unificate per le dipendenze per i moduli di bambino, senza specificare la versione in ogni modulo del bambino.

In Eclipse, c'è una caratteristica più nel dependencyManagement. Quando dependencies viene utilizzato senza di essa, le dipendenze non trovati si notano nel file pom. Se viene utilizzato dependencyManagement, le dipendenze irrisolti rimangono inosservati nel file POM e gli errori appaiono solo nei file java. (importazioni e tale ...)

La differenza tra i due è meglio portato in quello che sembra un definizione necessaria e sufficiente dell'elemento dependencyManagement disponibili nel sito web Maven docs

dependencyManagement

"informazioni di dipendenza di default per i progetti che ereditano da questo. Le dipendenze in questa sezione non sono immediatamente risolto. Al contrario, quando un POM derivato da questo dichiara una dipendenza descritta da un corrispondente groupId e artifactId, la versione e altri valori da questa sezione vengono utilizzati per la dipendenza che se non fossero già specificati." [ https://maven.apache.org/ref/3.6 .1 / Maven-model / maven.html ]

Si deve essere letto insieme ad un po 'di informazioni disponibili su una pagina diversa:

“.. il set minimo di informazioni per la corrispondenza un riferimento di dipendenza nei confronti di una sezione dependencyManagement è in realtà {groupId, artifactId, tipo, classificatore}. In molti casi, queste dipendenze faranno riferimento agli artefatti vaso senza classificatore. Questo ci permette di stenografia l'insieme identità {groupId, artifactId}, dal momento che il valore predefinito per il campo tipo è vaso, e il classificatore predefinito è nullo.”[ https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html ]

Così, tutti i sotto-elementi (portata, esclusioni ecc,) di un elemento di dipendenza - diversi groupId, artifactId, tipo, classificatore, non solo versione - sono disponibili per il blocco / default nel punto (e quindi ereditato da lì in poi) si specifica la dipendenza all'interno di una dependencyElement. Se avessi specificato una dipendenza con il tipo e classificatore sotto-elementi (vedere la prima citata pagina web per controllare tutti i sub-elementi) come non barattolo e non nullo, rispettivamente, avresti bisogno {groupId, artifactId, classificatore, type} di riferimento (risolvere) che dipendere in qualsiasi punto eredità proveniente dall'elemento dependencyManagement. Altrimenti, {groupId, artifactId} sarebbe sufficiente se non si ha intenzione di ignorare (rispettivamente vaso e null) i valori predefiniti per classificatore e tipo. Quindi, di default è una buona parola chiave in questa definizione; ogni sotto-elemento (s) (diversi groupId, artifactId, classificatore e tipo, naturalmente) il valore esplicitamente assegnato (s) nel punto di riferimento una sostituzione di dipendenza i valori predefiniti nell'elemento dependencyManagement.

Quindi, qualsiasi elemento di dipendenza esterna di dependencyManagement, sia come un riferimento a qualche elemento dependencyManagement o come un autonomo è risolto immediatamente (cioè installato al deposito locale e disponibili per percorsi di classe).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top