4 votes

Eviter une mauvaise interpolation de version si la version du pom de l'enfant est différente de celle de l'agrégateur pom du parent et de ses sous-modules.

Description du problème

Nous avons un pom d'agrégateur Maven avec quelques poms enfants (modules) ayant tous la même version :

pom.xml (parent zoo, version 2.0.0)
|-- pom.xml (child module cat, version 2.0.0)
|-- pom.xml (child module dog, version 2.0.0)
|-- ...

Dans la section de gestion des dépendances, tous les enfants sont déclarés avec la version du projet pour faciliter la déclaration des dépendances. Le pom parent ressemble à

<groupId>com.acme</groupId>
<artifactId>zoo</artifactId>
<version>2.0.0</version>
<packaging>pom</packaging>

<modules>
  <module>cat</module>
  <module>dog</module>
</modules>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.acme</groupId>
      <artifactId>cat</artifactId>
      <version>${project.version}</version>
    </dependency>
    <!-- other child modules go here -->
  </dependencies>
</dependencyManagement>

Les poms enfants sont définis comme suit

<parent>
  <groupId>com.acme</groupId>
  <artifactId>zoo</artifactId>
  <version>2.0.0</version>
</parent>

<groupId>com.acme</groupId>
<artifactId>cat</artifactId>

<dependencies>
  <dependency>
    <groupId>com.acme</groupId>
    <artifactId>dog</artifactId>
  </dependency>
</dependencies>

Il y a un autre pom qui déclare le pom parent comme son parent aussi (héritage) mais n'est pas listé comme sous-module dans ce parent (pas d'agrégation). Ce pom a une version différente.

<parent>
  <groupId>com.acme</groupId>
  <artifactId>zoo</artifactId>
  <version>2.0.0</version>
</parent>

<groupId>com.acme</groupId>
<artifactId>boo</artifactId>
<version>1.0.0</version>

<dependencies>
  <dependency>
    <groupId>com.acme</groupId>
    <artifactId>dog</artifactId>
  </dependency>
</dependencies>

En fait, nous nous attendions à ce que la version de la dépendance com.acme.dog est tiré de la section de gestion des dépendances du pom parent com.acme.zoo et est égal à 2.0.0 . Cependant, le Documentation Maven sur l'interpolation des projets et les variables dit

Un facteur à noter est que ces variables sont traitées après l'héritage comme indiqué ci-dessus. Cela signifie que si un projet parent utilise une variable, c'est sa définition dans le projet enfant, et non dans le projet parent, qui sera finalement utilisée.

C'est-à-dire : dans la construction du réacteur, la variable ${project.version} utilisé dans la section de gestion des dépendances du pom parent com.acme.zoo est évalué par rapport à com.acme.bar et égale à 1.0.0 ce qui n'est pas comme prévu.

Nota

Il existe une solution de contournement consistant à utiliser une variable dans le pom parent qui doit être maintenue en synchronisation avec les versions du pom parent. Cependant, cette solution est incompatible avec le Plugin Maven Release .

Question

Comment pouvons-nous obtenir le comportement souhaité

  • pom de l'agrégateur avec des enfants ayant la même version
  • déclaration des enfants dans la section de gestion des dépendances pour s'assurer que toutes les dépendances ont la même version
  • utilisation de l'héritage avec des versions différentes
  • la compatibilité avec maven-release-plugin

sans les écueils de l'interpolation des variables du projet ?

4voto

thuri Points 173

Le plugin maven release est capable de changer les versions des dépendances gérées dans le pom parent.

Donc si vous définissez votre parent maven comme ceci :

<groupId>com.acme</groupId>
<artifactId>zoo</artifactId>
<version>2.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
  <module>cat</module>
  <module>dog</module>
</modules>

<dependencyManagement>
 <dependencies>
   <dependency>
     <groupId>com.acme</groupId>
     <artifactId>cat</artifactId>
     <version>2.0.0-SNAPSHOT</version>
   </dependency>
   <!-- other child modules go here -->
 </dependencies>
</dependencyManagement>

Comme vous le voyez, les versions du parent et de la dépendance gérée sont les mêmes. Je les ai mis à une version SNAPSHOT parce que le plugin release créera les versions finales sur release:perform.

Vos poms d'enfants peuvent rester comme vous les aviez.

Parce que dans votre configuration, votre projet parent est également le réacteur, vous pouvez alors appeler

mvn release:perform -DautoVersionSubmodules=true

qui mettra à jour la version du parent dans tous les sous-modules lorsque vous exécuterez cette commande. Cette option est essentiellement la même que si vous exécutez la commande

mvn versions:update-child-modules

ce qui veut dire qu'il va changer les poms enfants.

Après avoir exécuté la commande mvn release:perform, votre pom parent ressemblera à ceci :

<groupId>com.acme</groupId>
<artifactId>zoo</artifactId>
<version>2.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
  <module>cat</module>
  <module>dog</module>
</modules>

<dependencyManagement>
 <dependencies>
   <dependency>
     <groupId>com.acme</groupId>
     <artifactId>cat</artifactId>
     <version>2.0.1-SNAPSHOT</version>
  </dependency>
  <!-- other child modules go here -->
 </dependencies>
</dependencyManagement>

et votre enfant fait des poms comme ceci

<parent>
  <groupId>com.acme</groupId>
  <artifactId>zoo</artifactId>
  <version>2.0.1-SNAPSHOT</version>
</parent>

<groupId>com.acme</groupId>
<artifactId>cat</artifactId>

<dependencies>
  <dependency>
    <groupId>com.acme</groupId>
    <artifactId>dog</artifactId>
  </dependency>
</dependencies>

Les versions finales n'existeront que dans le tag créé par la commande release:prepare.

PS : Vous pouvez définir d'autres versions pour la version finale et la prochaine version de développement lorsqu'elles sont demandées après l'exécution de la commande release:prepare.

2voto

michaldo Points 2358

La solution la plus simple est de modifier pom de zoo et de remplacer <version>${project.version}</version> con <version>2.0.0</version>

Veuillez noter :

  1. lorsque vous changez la version pour le numéro suivant, par exemple 2.0.1, avec versions-maven-plugin La section de gestion des dépendances sera également mise à jour.

  2. Spring utilise la solution la plus simple, voir http://central.maven.org/maven2/org/springframework/spring-framework-bom/4.2.7.RELEASE/spring-framework-bom-4.2.7.RELEASE.pom

Résumé : Utilisation <version>${project.version}</version> dans la gestion des dépendances est une mauvaise idée.

0voto

Mickael Points 2790

De Maven Introduction au pom : http://maven.apache.org/guides/introduction/introduction-to-the-pom.html

Héritage du projet > Exemple 1 > La solution

Alternativement, si nous voulons le groupId et / ou la version de votre modules soient les mêmes que leurs parents, vous pouvez supprimer l'identité groupId et / ou la version de votre module dans son POM.

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

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