102 votes

<dependencyManagement> et <scope>

Je mets généralement une section dans parent-project/pom.xml. Cette section contient la déclaration et la version de toutes les dépendances de mes modules enfants comme ceci (c'est-à-dire sans l'élément ):

      junit
      junit
      4.10

Dans tous les modules enfants (c'est-à-dire moduleX/pom.xml), j'ai:

     junit
     junit
     test

De toute évidence, dans cet exemple, je répète le test plusieurs fois pour la même dépendance (une fois dans chaque module enfant ayant besoin de junit).

Ma question est:
Quelles sont les meilleures pratiques concernant la déclaration du ?
Est-il préférable de le mettre dans le ?
Ou est-il préférable de le mettre dans la section du module enfant (comme dans ce post)? Et pourquoi?
Y a-t-il une réponse définitive à cette question?

82voto

Lucas Points 4891

Un peu en retard à la fête, mais je donnerai mon avis.

Récemment, j'ai rencontré un problème très difficile à déboguer.
J'ai un POM parent pour gérer les dépendances entre plusieurs projets. Je l'avais configuré avec toutes les dépendances communes entre eux et inclus groupId, artifactId, version et le scope le plus commun.
Je pensais que je n'aurais pas à inclure le scope dans la section de dépendance de chaque projet si cela correspondait à ce scope le plus commun.
Le problème est survenu lorsque certaines de ces dépendances sont apparues comme des dépendances transitives. Par exemple, si :

  • A dépend de B à portée de compilation.
  • B dépend de C à portée de compilation.
  • C est défini comme fourni dans la dependencyManagement du parent.

Alors la dépendance transitive de A sur C est déterminée comme fournie. Je ne suis pas vraiment sûr si cela a du sens ou non, mais cela peut certainement être déroutant.

Quoi qu'il en soit, épargnez-vous les tracas et laissez le scope en dehors de votre dependencyManagement.

40voto

Gab Points 1979

dependencyManagement est simplement là pour définir les versions des dépendances pour tous les sous-modules du projet, la seule portée pertinente dans cette section est import pour les BOM.

La portée doit être définie dans la section dépendances.

(Pour une dépendance donnée, cela détermine le contexte d'utilisation. Cela permet d'inclure la dépendance uniquement lorsqu'elle est nécessaire pour l'exécution. Par exemple, un ear ne sera pas empaqueté avec les dépendances Java-EE (portée fourni) car il les trouvera sur le serveur cible.)

[éditer]

La première déclaration a une exception, la portée fourni dans la section dependencyManagement remplacera la portée définie dans les sections dépendances. voir DependencyManagement to force scope

9voto

Peter Lapisu Points 145

Comme pour d'autres réponses, la meilleure pratique est d'exclure la portée de la gestion des dépendances et de la spécifier explicitement lors de la définition de la dépendance. Il est rare que vous vouliez une version différente de la même dépendance dans des portées différentes, par exemple une version lors de la compilation de votre application et une autre lors de son exécution - le seul cas auquel je peux penser est quand vous voulez exécuter explicitement vos tests avec une version différente d'une bibliothèque au cas où les utilisateurs utilisent cette version au lieu de celle que vous spécifiez.

Si vous définissez la portée dans la gestion des dépendances, cela restreint l'utilisation de cette version UNIQUEMENT à la portée définie - donc toute autre portée choisira une version aléatoire de la dépendance. J'ai rencontré ce problème hier lorsque nous avions défini junit 4.12 dans la gestion des dépendances avec la portée de test, mais notre module de framework de test commun utilisait junit avec la portée de compilation, il a donc récupéré la version 4.8.2 à la place.

2voto

Denis Wang Points 353

Très en retard à la fête, mais le dernier maven a une documentation très claire sur la portée des dépendances transitives et les détails de dependencyManagement, y compris un exemple. https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#dependency-scope à partir de la documentation, nous pouvons voir :

  1. lorsque les portées transitives sont différentes, il existe des règles de priorité régissant celle qui sera appliquée. À première vue, le tableau des règles est compliqué, mais il a du sens pour la plupart des cas.
  2. la documentation spécifique a notamment un exemple de cas combiné de portée de dépendance et de gestion de dépendance. finalement, il suit les règles spécifiées dans le point 1.

En conclusion, il est recommandé d'inclure la portée de la manière la plus 'commune'. En cas de cas transitifs, conflictuels ou complexes, nous devons vérifier attentivement les règles de priorité.

1voto

kostja Points 20153

Il n'y a aucun avantage à ajouter une seule dépendance à la gestion des dépendances, pour quelque portée que ce soit. Tout ce que vous avez, c'est la duplication. Si vous voulez que la version soit configurable, ajoutez une propriété et utilisez-la dans votre dépendance :

        4.10 
    ...

        junit
        junit
        ${junit.version}

Cependant, il existe des cas où la gestion des dépendances brille - lorsque vous utilisez des bom afin d'orchestrer les versions pour une plus grande collection d'artefacts, comme l'utilisation d'une certaine version d'une implémentation Java EE :

            org.jboss.bom
            jboss-javaee-6.0-with-tools
            ${javaee6.with.tools.version}
            pom
            import

....

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X