Diferencias entre dependencyManagement y dependencias en Maven


¿Cuál es la diferencia entre dependencyManagement y dependencies? He visto los documentos en el sitio web Apache Maven. Parece que una dependencia definida bajo dependencyManagement puede ser usada en sus módulos secundarios sin especificar la versión.

Por ejemplo:

Un proyecto padre (Pro-par) define una dependencia bajo el dependencyManagement:

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

Entonces en el hijo de Pro-par, puedo usar el 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?

Author: M. Justin, 2010-04-12

9 answers

Dependency Management permite consolidar y centralizar la gestión de versiones de dependencias sin añadir dependencias heredadas por todos los hijos. Esto es especialmente útil cuando tiene un conjunto de proyectos (es decir, más de uno) que hereda un padre común.

Otro caso de uso extremadamente importante de dependencyManagement es el control de versiones de artefactos usados en dependencias transitivas. Esto es difícil de explicar sin un ejemplo. Por suerte, esto es ilustrado en la documentación.

 335
Author: Pascal Thivent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-12 03:31:11

Estoy a la moda tarde para esta pregunta, pero creo que vale la pena una respuesta más clara que la aceptada (que es correcta, pero no enfatiza la parte importante real, que necesita deducir usted mismo).

En el POM padre, la principal diferencia entre <dependencies> y <dependencyManagement> es esto:

Artefactos especificados en el <dependencies> la sección SIEMPRE se incluirá como una dependencia de los módulos secundarios.

Artefactos especificados en el <dependencyManagement> sección, sólo se incluirán en el niño módulo si se especifica también en el <dependencies> la sección del niño módulo de sí mismo. ¿Por qué es bueno que preguntes? porque especifica la versión y / o el ámbito en el padre, y puede omitirlos al especificar las dependencias en el POM hijo. Esto puede ayudarlo a usar versiones unificadas para dependencias para módulos secundarios, sin especificar la versión en cada módulo secundario.

 429
Author: dcoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-17 16:04:49

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

Se vuelve útil cuando tiene varios atributos que no desea volver a escribir en varios proyectos hijos.

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

 43
Author: Pran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-12 03:08:45

La documentación en el sitio Maven es horrible. Lo que hace dependencyManagement es simplemente mover sus definiciones de dependencia (versión, exclusiones, etc.) hasta el pom padre, luego en el pom hijo solo tiene que poner el groupId y artifactId. Eso es todo (excepto para el encadenamiento pom padre y similares, pero eso no es realmente complicado tampoco-dependencyManagement gana sobre las dependencias en el nivel padre-pero si tiene una pregunta sobre eso o las importaciones, el Maven la documentación es un poco mejor).

Después de leer toda la basura 'a', 'b', 'c' en el sitio de Maven y confundirme, reescribí su ejemplo. Así que si tienes 2 proyectos (proj1 y proj2) que comparten una dependencia común (betaShared) podrías mover esa dependencia hasta el pom padre. Mientras está en ello, también puede mover hacia arriba cualquier otra dependencia (alpha y charlie), pero solo si tiene sentido para su proyecto. Así que para la situación descrita en las oraciones anteriores, aquí está la solución con dependencyManagement en el pom padre:

<!-- 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>
 39
Author: MattC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 03:39:33

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

Este es un ejemplo incremental:

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 mi Child A, Child B y Child C módulos:

  • Implicitud heredada por el niño poms
  • Un único lugar para gestionar
  • No hay necesidad de volver a declarar nada en poms para niños
  • Todavía puedo redelcare y override a {[5] } en un Child B si quiero.

Pero ¿qué pasa si termino sin necesitar guayaba en Child C, y tampoco en los módulos futuros Child D y Child E?

¡Todavía lo heredarán y esto no es deseado! Esto es como Java God Object code smell, donde heredas algunos bits útiles de una clase, y una tonelada de cosas no deseadas también.

Aquí es donde <dependencyManagement> entra en juego. Cuando agrega esto a su pom padre, todos sus módulos hijos DEJAN de verlo. Y así tú son obligados a entrar en cada módulo individual que LO necesita y declararlo de nuevo (Child A y Child B, sin embargo, sin la versión).

Y, obviamente, no lo haces para Child C, y por lo tanto tu módulo sigue siendo delgado.

 11
Author: Andrejs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-17 11:27:41

Si la dependencia estaba definida en el elemento dependencyManagement del pom de nivel superior, el proyecto hijo no tenía que listar explícitamente la versión de la dependencia. si el proyecto hijo definiera una versión, anularía la versión listada en el nivel superior Sección de gestión de la dependencia de POM. Es decir, la versión dependencyManagement es solo se usa cuando el hijo no declara una versión directamente.

 8
Author: Mustafa Güven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-11 14:18:19

Hay algunas respuestas que describen las diferencias entre las etiquetas <depedencies> y <dependencyManagement> con maven.

Sin embargo, pocos puntos se desarrollan a continuación de manera concisa:

  1. <dependencyManagement> permite consolidar todas las dependencias (usadas a nivel pom hijo) usadas a través de diferentes módulos { claridad, administración central de versiones de dependencias
  2. <dependencyManagement> permite actualizar / degradar fácilmente dependencias basadas en la necesidad, en otro escenario esto debe ejercerse en cada hijo nivel pom consistency consistencia
  3. las dependencias proporcionadas en la etiqueta <dependencies> siempre se importan, mientras que las dependencias proporcionadas en <dependencyManagement> en el pom padre solo se importarán si el pom hijo tiene una entrada respectiva en su etiqueta <dependencies>.
 7
Author: Amit Kaneria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-22 11:20:40

En el POM padre, la principal diferencia entre <dependencies> y <dependencyManagement> es esta:

Los artefactos especificados en la sección <dependencies> SIEMPRE se incluirán como una dependencia de los módulos secundarios.

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

 3
Author: Yaver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-10 02:40:14

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 no resueltas permanecen desapercibidas en el archivo pom y los errores solo aparecen en los archivos java. (importaciones y tal...)

 1
Author: Gangnus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-06 14:47:12