¿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 bajo el dependencyManagement
se puede utilizar en sus módulos secundarios sin especificar la versión.
Por ejemplo:
Un proyecto padre (Pro-par) define una dependencia bajo dependencyManagement
:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8</version>
</dependency>
</dependencies>
</dependencyManagement>
Luego, 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?
fuente
<dependencyManagement>
en el POM principal. La inclusión de dependencias en<dependencyManagement>
la gestión centralizada de la versión, el alcance y las exclusiones para cada dependencia, si decide utilizarla y cuándo. La guía de Maven para la gestión de dependencias entra en todos los detalles.dependencyManagement
también controla las dependencias transitivas) solo es cierto cuando las dependencias se establecen explícitamente: stackoverflow.com/questions/28312975/…dependencies
sección en su pom padre. Lo hicimos para que todos los proyectos secundarios tengan algunos apache-commons por defecto y no declararlos todo el tiempo.Llego tarde a esta pregunta, pero creo que merece una respuesta más clara que la aceptada (lo cual es correcto, pero no enfatiza la parte importante real, que debes deducir).
En el POM padre, la principal diferencia entre
<dependencies>
y<dependencyManagement>
es esta:Los artefactos especificados en la
<dependencies>
sección SIEMPRE se incluirán como una dependencia de los módulos secundarios.Los artefactos especificados en la
<dependencyManagement>
sección solo se incluirán en el módulo secundario si también se especificaron en la<dependencies>
sección del propio módulo secundario. ¿Por qué es bueno lo preguntas? 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.fuente
<dependencyManagement>
más<dependencies>
en la raíz.pom
? El niñopom
puede ser mucho más bajo.Artifacts specified in the <dependencies> section will ALWAYS be included as a dependency of the child module(s)
que también están incluidos en el padre. Parece que no es posible establecer una dependencia para los hijos, pero no para el padre.La documentación 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 los poms secundarios solo tiene que poner groupId y artifactId. Eso es todo (excepto el encadenamiento de pom padres y similares, pero eso tampoco es realmente complicado: dependencyManagement vence a las dependencias en el nivel primario, pero si tiene alguna pregunta sobre eso o importaciones, 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, reescribí su ejemplo. Entonces, si tenía 2 proyectos (proj1 y proj2) que comparten una dependencia común (betaShared), podría mover esa dependencia al pom padre. Mientras lo hace, también puede subir cualquier otra dependencia (alfa y charlie) pero solo si tiene sentido para su proyecto. Entonces, para la situación descrita en las oraciones anteriores, aquí está la solución con dependencyManagement en el padre pom:
fuente
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 desea volver a escribir en múltiples proyectos secundarios.
Finalmente,
dependencyManagement
se puede usar para definir una versión estándar de un artefacto para usar en múltiples proyectos.fuente
Todavía hay una cosa que no se destaca lo suficiente, en mi opinión, y que es la herencia no deseada .
Aquí hay un ejemplo incremental:
Declaro en mi
parent
pom:¡auge! Lo tengo en mi
Child A
,Child B
yChild C
módulos:version 18.0
en unChild B
si quiero.Pero, ¿qué pasa si termino sin necesitar guayaba
Child C
, y tampoco en el futuroChild D
y losChild E
módulos?¡Todavía lo heredarán y esto no es deseado! Esto es como el olor del código de objeto de Dios Java, donde heredas algunos bits útiles de una clase, y también una tonelada de cosas no deseadas.
Aquí es donde
<dependencyManagement>
entra en juego. Cuando agrega esto a su pom padre, todos sus módulos secundarios DEJAN de verlo . Y por lo tanto, se ve obligado a entrar en cada módulo individual que lo necesita y declararlo nuevamente (Child A
yChild B
, sin embargo, sin la versión).Y, obviamente, no lo hace
Child C
, y por lo tanto su módulo sigue siendo delgado.fuente
<dependencyManagement>
en el pom padre, por defecto, las dependencias no se heredarán en los poms secundarios? Porque en el documento: maven.apache.org/guides/introduction/… mientras se explica el segundo uso del<dependencyManagement>
parece que se heredará de forma predeterminada. En una línea dicen que: "Cuando Maven se ejecuta en el proyecto B, la versión 1.0 de los artefactos a, b, c y d se usará independientemente de la versión especificada en su pom" aunque "b" no se use en el proyecto BHay algunas respuestas que describen las diferencias
<depedencies>
y las<dependencyManagement>
etiquetas con Maven.Sin embargo, algunos puntos se detallan a continuación de manera concisa:
<dependencyManagement>
permite consolidar todas las dependencias (utilizadas a nivel de pom hijo) utilizadas en diferentes módulos: claridad , gestión de versiones de dependencia central<dependencyManagement>
permite actualizar / degradar dependencias fácilmente según la necesidad, en otro escenario, esto debe ejercerse en cada nivel de pom infantil: consistencia<dependencies>
etiqueta siempre se importan, mientras que las dependencias proporcionadas<dependencyManagement>
en el pom principal se importarán solo si el pom secundario tiene una entrada respectiva en su<dependencies>
etiqueta.fuente
Lo siento, llego muy tarde a la fiesta.
Déjame intentar explicar la diferencia usando
mvn dependency:tree
comandoConsidere el siguiente ejemplo
Parent POM - My Project
Child POM - módulo de datos
Child POM - módulo de aplicación (no tiene dependencia adicional, por lo que deja las dependencias vacías)
Al ejecutar el
mvn dependency:tree
comando, obtenemos el siguiente resultadoGoogle guava aparece como dependencia en todos los módulos (incluido el padre), mientras que apache commons aparece como dependencia solo en el módulo de datos (ni siquiera en el módulo padre)
fuente
Si la dependencia se definió en el elemento de gestión de dependencia del pom de nivel superior, el proyecto secundario no tenía que enumerar explícitamente la versión de la dependencia. si el proyecto secundario definió una versión, anularía la versión que figura en la sección de gestión de dependencias del POM de nivel superior. Es decir, la versión de dependencyManagement solo se usa cuando el hijo no declara una versión directamente.
fuente
En el POM padre, la principal diferencia entre
<dependencies>
y<dependencyManagement>
es esta:Artefactos especificados en el
<dependencies>
sección 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 secundario si también se especificaron en la sección del propio módulo secundario. ¿Por qué es bueno lo preguntas? 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 de módulos secundarios, sin especificar la versión en cada módulo secundario.
fuente
Solo en mis propias palabras, tu
parent-project
ayuda a proporcionar 2 tipos de dependencias:<dependencies>
sección en tuparent-project
son heredadas por todos loschild-projects
child-projects
. Por lo tanto, usa la<dependencyManagement>
sección, para declarar todas las dependencias que va a usar en sus diferenteschild-projects
. Lo más importante es que, en esta sección, defina un<version>
para que no tenga que volver a declararlo en suchild-project
.En
<dependencyManagement>
mi punto de vista (corrígeme si estoy equivocado) es útil al ayudarte a centralizar la versión de tus dependencias. Es como una especie de función auxiliar.fuente
En Eclipse, hay una característica más en el
dependencyManagement
. Cuandodependencies
se usa sin él, las dependencias no encontradas se notan en el archivo pom. SidependencyManagement
se usa, las dependencias no resueltas pasan desapercibidas en el archivo pom y los errores solo aparecen en los archivos java. (importaciones y tal ...)fuente
La diferencia entre los dos se presenta mejor en lo que parece una definición necesaria y suficiente del elemento de dependencia de gestión disponible en los documentos del sitio web de Maven:
gestión de dependencia
"Información de dependencia predeterminada para proyectos que heredan de este. Las dependencias en esta sección no se resuelven de inmediato. En cambio, cuando un POM derivado de este declara una dependencia descrita por un groupId y artifactId coincidentes, la versión y otros valores de esta sección se usan para esa dependencia si aún no se especificaron ". [ https://maven.apache.org/ref/3.6.1/maven-model/maven.html ]
Debe leerse junto con más información disponible en una página diferente:
"... el conjunto mínimo de información para hacer coincidir una referencia de dependencia con una sección de gestión de dependencia es en realidad {groupId, artifactId, type, classifier}. En muchos casos, estas dependencias se referirán a artefactos jar sin clasificador. Esto nos permite abreviar la identidad establecida en {groupId, artifactId}, ya que el valor predeterminado para el campo de tipo es jar, y el clasificador predeterminado es nulo ". [ https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html ]
Por lo tanto, todos los subelementos (alcance, exclusiones, etc.) de un elemento de dependencia, que no sean groupId, artifactId, type, clasifier, no solo version, están disponibles para bloqueo / default en el punto (y por lo tanto se heredan de allí adelante) usted especifica la dependencia dentro de un dependencyElement. Si hubiera especificado una dependencia con los subelementos de tipo y clasificador (consulte la primera página web citada para verificar todos los subelementos) como no jar y no nulo respectivamente, necesitaría {groupId, artifactId, classifier, type} para hacer referencia (resolver) esa dependencia en cualquier punto de una herencia que se origina en el elemento dependencyManagement. De lo contrario, {groupId, artifactId} sería suficiente si no tiene la intención de anular los valores predeterminados para clasificador y tipo (jar y null respectivamente). Entonces, el valor predeterminado es una buena palabra clave en esa definición; cualquier subelemento (s) (distinto de groupId,
Por lo tanto, cualquier elemento de dependencia fuera de dependencyManagement, ya sea como referencia a algún elemento de dependencyManagement o como independiente, se resuelve de inmediato (es decir, se instala en el repositorio local y está disponible para classpaths).
fuente