2010-04-12 27 views
447

¿Cuál es la diferencia entre dependencyManagement y dependencies? He visto los documentos en el sitio web de Apache Maven. Parece que una dependencia definida en dependencyManagement se puede utilizar en sus módulos secundarios sin especificar la versión.diferencias entre dependencymanagement y dependencias en maven

Por ejemplo:

Un proyecto principal (Pro-par) define una dependencia bajo la dependencyManagement:

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

Luego, en el niño de Pro-par, puedo usar la junit:

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

Sin embargo, me pregunto si es necesario definir junit en el pom padre? ¿Por qué no definirlo directamente en el módulo necesario?

Respuesta

291

Dependency Management permite consolidar y centralizar la administración de versiones de dependencia sin agregar dependencias heredadas por todos los elementos secundarios. Esto es especialmente útil cuando tiene un conjunto de proyectos (es decir, más de uno) que hereda un elemento primario común.

Otro caso de uso extremadamente importante de dependencyManagement es el control de versiones de artefactos utilizados en dependencias transitivas. Esto es difícil de explicar sin un ejemplo. Afortunadamente, esto se ilustra en la documentación.

+14

Por lo tanto, su necesidad de declarar dependencias en el pom del proyecto hijo de todos modos, incluso si declararon en el pom del proyecto principal en la sección ? ¿Es posible hacer algún tipo de herencia de dependencias? –

+30

Sí, aún necesita definirlos en el POM hijo para mostrar que los está usando. En realidad, no se incluyen en los proyectos secundarios solo porque están en '' en el POM principal. La inclusión de dependencias en '' centraliza la administración de la versión, el alcance y las exclusiones para cada dependencia, siempre y cuando decida usarla. Maven [guía para la gestión de la dependencia] (http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html # Dependency_Management) entra en todos los detalles. – hotshot309

+1

El segundo párrafo ('dependencyManage' también controla las dependencias transitivas) solo es verdadero cuando las dependencias se establecen explícitamente: http://stackoverflow.com/questions/28312975/maven-dependencymanagement-version-ignored-in-transitive-dependencies –

39

Es como dijiste; dependencyManagement se utiliza para extraer toda la información de dependencia en un archivo POM común, simplificando las referencias en el archivo POM secundario.

Se vuelve útil cuando tiene múltiples atributos que no quiere volver a escribir en varios proyectos secundarios.

Finalmente, dependencyManagement se puede utilizar para definir una versión estándar de un artefacto para usar en varios proyectos.

+3

Entonces, las dependencias no heredan? ¿Tiene que declararse de todos modos en el pom del proyecto secundario? –

+3

Sí, debe declararlos de todos modos en proyectos para niños, pero sin especificar una versión. –

2

En Eclipse, hay una característica más en el dependencyManagement. Cuando dependencies se usa sin él, las dependencias no encontradas se notan en el archivo pom. Si se usa dependencyManagement, las dependencias sin resolver permanecen desapercibidas en el archivo pom y los errores aparecen solo en los archivos java. (importaciones y tal ...)

-13

Si tiene casos de prueba JUnit definidos en todos los módulos secundarios y está utilizando STS o eclipse, con solo definir eclipse dará errores para los casos de prueba.

Necesita agregar dependencias para junit outside tag en el módulo principal, para que no se produzcan errores en los casos de prueba en eclipse. Aunque maven aún compilará sin tener este tipo de etiqueta

+0

what tipo de respuesta es esta, me hace reír! – CuriousMind

8

Si la dependencia se definió en el elemento de dependencia de gestión pom del nivel superior, el proyecto secundario no tuvo que enumerar explícitamente la versión de la dependencia. si el proyecto hijo definió una versión, anularía la versión enumerada en la sección de gestión de dependencias del POM de nivel superior . Es decir, la versión de dependencyManagement es solo cuando el hijo no declara una versión directamente.

+0

Creo que esta afirmación puede no ser correcta. En los ejemplos de Maven's Dependency Management (# 2), dicen que las dependencias definidas en un pom padre con una versión anularán la versión especificada en el pom hijo: "Cuando maven se ejecuta en el proyecto B versión 1.0 de los artefactos a, b, c y d se usará independientemente de la versión especificada en su pom ". – devdanke

+0

@devdanke Al menos, Eclipse m2e emite una advertencia: _Volver a la versión administrada ... para ..._. –

34

El documentation en el sitio de Maven es horrible.Lo que hace dependencyManagement es simplemente mover sus definiciones de dependencia (versión, exclusiones, etc.) al pom padre, luego en las poms secundarias solo tiene que poner groupId y artifactId. Eso es todo (excepto para el pomcate de padres y cosas por el estilo, pero tampoco es realmente complicado - dependencyManagement gana sobre las dependencias en el nivel principal - pero si tiene una pregunta sobre eso o importa, la documentación de Maven es un poco mejor).

Después de leer toda la basura 'a', 'b', 'c' en el sitio de Maven y confundirme, volví a escribir su ejemplo. Entonces, si tuviera 2 proyectos (proj1 y proj2) que compartan una dependencia común (betaShared), podría mover esa dependencia al pom padre. Mientras lo hace, también puede mover cualquier otra dependencia (alfa y charlie), pero solo si tiene sentido para su proyecto. Así que para la situación descrita en las frases anteriores, aquí está la solución con DependencyManagement en el pom padres:

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

Pregunta un tanto fuera de tema: ¿qué significa el tipo de dependencia "barra"? Vi en un ejemplo pom en la documentación de Maven, pero no pude encontrar una definición. Supuse que era un error de "guerra" o "jarra", pero lo veo en otros ejemplos como el tuyo. – NobodyMan

+0

NobodyMan - Por lo tanto, es solo un marcador de posición para otro tipo de archivo. Como usar 'foo'. O podría usarse si alguien hizo un tipo personalizado con la extensión 'bar'. Y hay muchos tipos de archivos oscuros por ahí. Como sar, que es el archivo de servicio jboss. – MattC

+1

esta es la mejor respuesta. muy claro y fácil de seguir –

303

estoy elegantemente tarde a esta pregunta, pero creo que vale la pena una respuesta más clara que la aceptó una (que es correcto, pero no enfatiza la parte realmente importante, que necesita deducirse a sí mismo).

En el POM padres, la diferencia principal entre el <dependencies> y <dependencyManagement> es la siguiente:

Los artefactos que se especifican en la sección <dependencies> siempre se incluirá como una dependencia del módulo de niño (s) .

Los artefactos que se especifican en la sección <dependencyManagement>, solamente se incluirán en el módulo niño si también se especifican en la sección <dependencies> del propio módulo de niño. ¿Por qué es bueno que preguntes? porque especifica la versión y/o el alcance en el elemento primario, y puede omitirlos al especificar las dependencias en el POM secundario. Esto puede ayudarlo a usar versiones unificadas para dependencias para módulos secundarios, sin especificar la versión en cada módulo secundario.

+56

esta es una explicación mucho mejor que la respuesta elegida. –

+0

Pero, ¿no es también una sobrecarga, usando '' sobre '' en la raíz '.pom'? Child 'pom's podría ser mucho más corto. –

+2

Eso es verdad. Usar en lugar de creará poms secundarios más cortos. Sin embargo, viene con un costo, significa que esas dependencias SIEMPRE se definirán para TODOS los módulos secundarios. Si solo ALGUNOS de los módulos secundarios necesitan una cierta dependencia, el uso de "" le permitiría elegir qué módulos secundarios tendrán esa dependencia y aún así ser un poco eficientes configurando la versión de dependencia solo en el pom principal. – dcoder

5

Hay pocas respuestas que resuelvan las diferencias entre <depedencies>/<dependencyManagement> etiquetas con maven.

Sin embargo, algunos puntos desarrollan a continuación de una manera concisa:

  1. <dependencyManagement> permite consolidar todas las dependencias (utilizado a nivel pom niño) que se utiliza a través de diferentes módulos - claridad, dependencia central de gestión de versiones
  2. <dependencyManagement> permite actualizar/degradar dependencias fácilmente en función de la necesidad, en otro caso, esto debe ejercerse en todos los niveles de pom de niño - consistencia
  3. dependencias previstas en <dependencies> etiqueta siempre se importan, mientras que las dependencias previstas en <dependencyManagement> en pom padres serán importados sólo si pom niño tiene entrada respectiva
1

Todavía hay una cosa que no se destaca lo suficiente, en mi opinión, y eso es herencia no deseada.

He aquí un ejemplo elemental:

declaro en mi parent pom:

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

boom! Lo tengo en mis módulos Child A, Child B y Child C:

  • Implicilty heredado por poms del niño
  • un único lugar para administrar
  • No hay necesidad de redeclare nada en poms del niño
  • Todavía puedo redelcare y anular a version 18.0 en un Child B si quiero.

Pero lo que si termino sin necesidad de guayaba en Child C, y tampoco en el futuro Child D y Child E módulos?

¡Lo heredarán y esto no es deseado! Esto es como el código del objeto Java God, donde heredas algunas partes útiles de una clase, y un montón de cosas no deseadas también.

Aquí es donde entra en juego <dependencyManagement>. Cuando agrega esto a su pom principal, todos sus módulos secundarios DEJAN de verlo. Y así usted está forzado para entrar en cada módulo individual que LO NECESITA y declararlo nuevamente (Child A y Child B, sin la versión).

Y, obviamente, no lo hace para Child C, y por lo tanto su módulo sigue siendo pobre.

1

En el POM padres, la diferencia principal entre el <dependencies> y <dependencyManagement> es la siguiente:

Los artefactos que se especifican en la sección <dependencies> siempre se incluirá como una dependencia del módulo (s) hijo.

Los artefactos especificados en la sección solo se incluirán en el módulo secundario si también se especificaron en la sección del módulo hijo. ¿Por qué es bueno que preguntes? porque especifica la versión y/o el alcance en el elemento primario, y puede omitirlos al especificar las dependencias en el POM secundario. Esto puede ayudarlo a usar versiones unificadas para dependencias para módulos secundarios, sin especificar la versión en cada módulo secundario.