web-dev-qa-db-fra.com

dependencyManagement and scope

Je mets habituellement un <dependencyManagement> section dans parent-project/pom.xml. Cette <dependencyManagement> la section contient la déclaration et la version pour toutes les dépendances de mes modules enfants comme ceci (c'est-à-dire sans le <scope> élément):

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

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

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

Évidemment, dans cet exemple, je répète le <scope>test</scope> plusieurs fois pour la même dépendance (une fois dans chaque module enfant nécessitant junit).

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

49
ben75

Un peu tard pour la fête, mais je vais ajouter mes deux cents. J'ai récemment rencontré un problème très difficile à déboguer. J'ai un pom parent pour gérer les dépendances sur plusieurs projets. Je l'ai fait définir avec toutes les dépendances communes entre elles et inclus groupId, artifactId, version et le portée la plus courante. Je pense que je n'aurais pas à inclure la portée dans la section des dépendances réelles de chaque projet si elle correspondait à cette portée la plus courante. Le problème s'est produit lorsque certaines de ces dépendances sont apparues comme des dépendances transitives. Par exemple si

  • A dépend de B à la portée de compilation
  • B dépend de C à la portée de compilation
  • C est défini sur fourni dans dependencyManagement of parent

Il est alors déterminé que la dépendance transitive de A sur C est fournie. Je ne sais pas vraiment si cela a du sens ou non, mais c'est certainement déroutant.

Quoi qu'il en soit, évitez les tracas et laissez la portée hors de votre dépendance.

46
Lucas

dependencyManagement est juste là pour définir la version des dépendances pour tous les sous-modules du projet, la seule étendue pertinente dans cette section est import pour les nomenclatures.

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

(Pour une dépendance donnée, il détermine le contexte d'utilisation. Il permet d'inclure la dépendance uniquement lorsqu'elle est requise pour l'exécution. Par exemple, une oreille ne sera pas empaquetée avec les dépendances Java-ee (portée provided ) car il les trouvera sur le serveur cible.)

[modifier]

La première instruction a une exception, la portée provided dans la section dependencyManagement remplacera la portée définie dans les sections dependencies. voir DependencyManagement pour forcer la portée

20
Gab

Comme pour les autres réponses, la meilleure pratique consiste à exclure la portée de dependencyManagement et à la spécifier explicitement lors de la définition de la dépendance. Il est rare que vous souhaitiez une version différente de la même dépendance dans différentes étendues, 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 que vous souhaitez exécuter explicitement votre teste une version différente d'une bibliothèque au cas où les utilisateurs utiliseraient cette version au lieu de celle que vous spécifiez.

Si vous définissez l'étendue dans dependencyManagement, cela restreint l'utilisation de cette version à UNIQUEMENT l'étendue définie, de sorte que toute autre étendue récupérera une version aléatoire de la dépendance. J'ai rencontré cela hier lorsque nous avions défini junit 4.12 dans dependencyManagement avec la portée de test, mais notre module de cadre de test commun utilisait junit avec la portée de compilation, il a donc repris la version 4.8.2 à la place.

3
Phil

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

<properties>
        <junit.version>4.10</junit.version> 
    ...
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
    </dependency>
</dependencies>

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

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.bom</groupId>
            <artifactId>jboss-javaee-6.0-with-tools</artifactId>
            <version>${javaee6.with.tools.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
....
2
kostja