2009-09-08 22 views
14

Digamos que tengo dos dependencias de Maven definidas en un proyecto como el siguiente.Dependencia de Maven dentro de la dependencia con diferente alcance

<dependency> 
     <groupId>com.thoughtworks.xstream</groupId> 
     <artifactId>xstream</artifactId> 
     <version>1.3.1</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>mycompany.library</groupId> 
     <artifactId>mylibrary</artifactId> 
     <version>1.0.1</version> 
     <scope>compile</scope> 
    </dependency> 

Luego, dentro de mylibrary, también tengo una dependencia definida a continuación.

<dependency> 
     <groupId>com.thoughtworks.xstream</groupId> 
     <artifactId>xstream</artifactId> 
     <version>1.3.1</version> 
     <scope>compile</scope> 
    </dependency> 

Cuando Empaqueto mi proyecto, no veo xstream empaquetado dentro de ella. Creo que el alcance de la dependencia xstream del proyecto, 'test', está anulando el alcance de la dependencia xstream de mylibrary, 'compilar'.

En este tipo de situación, ¿cuál es la mejor manera de incluir el xstream para todo el proyecto para que el submódulo pueda tener acceso a él cuando se empaqueta dentro del proyecto?

He leído la explicación del sitio web de Apache Maven sobre las dependencias transitorias, pero estoy luchando por comprender lo que significa, y también para encontrar las mejores prácticas en esta situación.

Respuesta

11

Esto me parece realmente extraño, y si es "función", creo que es realmente peligroso. De todos modos, no es un error de Maven y está en la documentación de maven here.

En cuanto a las mejores prácticas en este tema, no he oído hablar de ninguna, pero la forma más segura de proceder debería ser eliminar por completo xstream de su pom, basándose en la dependencia transitiva. Hacer esto dará como resultado una falla de compilación si se elimina la dependencia a mylibrary. Esto actuará como una notificación para usted que necesita arreglar algo. No perderá silenciosamente las dependencias requeridas, y no tendrá silenciosamente dependencias que ya no necesita.

En una nota lateral, mvn dependency: analyze se puede utilizar para verificar las dependencias que se incluyen pero no se utilizan.

0

Si lo quiere embalado, ¿por qué está declarando alcance? Si es necesario en tiempo de compilación y ejecución, ¿no debería dejar el ámbito en blanco? Si hiciera eso, entonces sólo tendría que

<dependency> 
    <groupId>mycompany.modules</groupId> 
    <artifactId>submodule</artifactId> 
    <version>1.0.1</version> 
</dependency> 

en su pom. ¿A menos que exista un motivo para descartarlo durante la compilación, pero no durante el embalaje?

+0

del sitio web de Apache Maven: - compilar Este es el alcance predeterminado, se utiliza si no se especifica ninguno. Las dependencias de compilación están disponibles en todos los classpaths de un proyecto. Además, esas dependencias se propagan a proyectos dependientes. –

+0

Tal vez mi pregunta original causó confusión porque utilicé 'submódulo'. Por favor vea mi pregunta editada arriba. –

+0

Sí, me preguntaba más sobre el alcance de la prueba. – aperkins

4

Al declarar su propia dependencia en xstream y establecer el alcance para probar, está anulando las dependencias declaradas por mylibrary.

Esto es realmente una función Maven: le permite hacer cosas como depender de una versión posterior de una dependencia transitiva dentro de su propio proyecto, y no terminar empaquetando dos versiones diferentes del mismo artefacto. Por ejemplo, puede depender de la versión 1.2.15 de log4j, pero como también usa libraryX, que depende de log4j-1.2.14, no desea que se empaqueten con su proyecto log4j-1.2.15 y log4j-1.2.14.

Si realmente desea que xstream se empaquete dentro de su proyecto, no debe declarar el alcance como test. De hecho, si elimina su dependencia de la lista de xstream, todo saldrá bien, ya que mylibrary tiene una dependencia de compilación en él ...

+1

En ese caso, si en algún momento en el futuro, no necesito usar mylibrary o esa biblioteca cambia su dependencia en xstream a otra cosa, mi proyecto no pasará las pruebas. Luego, tendré que especificar xstream para el alcance de la prueba del proyecto nuevamente. ¿Es esta función/limitación de Maven? Estoy dispuesto a aceptar las limitaciones de Maven, solo estoy tratando de ver cuál es la mejor práctica. –

+0

No estoy seguro de que esto sea correcto. Hay un mecanismo más intuitivo para excluir dependencias transitivas no deseadas, y ese es el bloque . – Buhb

+0

"si en algún momento en el futuro, no necesito usar mylibrary o esa biblioteca cambia su dependencia de xstream a otra cosa, mi proyecto no pasará las pruebas". luego, en ese punto simplemente agrega la dependencia de nuevo. Mientras continúe confiando en la misma versión de mylibrary, no deberían ocurrir cambios inesperados. Las nuevas versiones de su proyecto pueden tener diferentes necesidades, lo cual es totalmente normal. –

5

Como dice la respuesta de mattb, al declarar la dependencia como test, el alcance anula la declaración de dependencia del ámbito de la compilación transitiva, y como resultado, la dependencia no se incluye en su guerra empaquetada.

Si solo necesita la dependencia en sus pruebas porque 'mylibrary' necesita que se ejecute, no debe declarar la dependencia en todo en el pom de su proyecto. Deje que el proceso de resolución de dependencia transitiva lo maneje.

Si su proyecto utiliza el contenedor xstream directamente, puede confiar en la dependencia transitiva, ya que necesitará una versión compatible para su proyecto y 'mylibrary' para que ambos se ejecuten en el contenedor xstream. Debería tener pruebas unitarias que ejerzan la funcionalidad, y si mylibrary cambia la versión de xstream a una versión incompatible, sus compilaciones deberían fallar y usted puede abordar el problema en ese punto.

En general, diría que debe intentar evitar declarar versiones de dependencia directamente en proyectos de varios módulos. Declaro las versiones en una sección dependencyManagement de un POM padre, de modo que el niño solo necesita declarar groupId/artifactId. Como alternativa, desde Maven 2.0.9 en adelante hay un alcance dependencia adicional de import:

Este alcance sólo se utiliza en una dependencia de tipo pom en la sección. Indica que el POM especificado debe reemplazarse con las dependencias en la sección de ese POM. Dado que son reemplazados, las dependencias con un alcance de importación en realidad no participan en la limitación de la transitividad de una dependencia.

Así, utilizando el alcance de importación puede definir sus versiones comunes de dependencia en una sola POM, importar las dependencias de ese POM en su sección DependencyManagement, y acaba de declarar la groupId/artifactId de la dependencia en el otro los POM.

Cuestiones relacionadas