Héritage de version du projet Maven - Dois-je spécifier la version parente?

197

J'ai deux projets: Projet parent: A, Sous-projet: B

A / pom.xml:

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>

Et en B / pom.xml, j'ai:

    <parent>
        <groupId>com.dummy.bla</groupId>
        <artifactId>parent</artifactId>
        <version>0.1-SNAPSHOT</version>     
    </parent>

    <groupId>com.dummy.bla.sub</groupId>
    <artifactId>kid</artifactId>

Je veux que B hérite de la version du parent, donc le seul endroit dans mon cas que je dois mettre 0.1-SNAPSHOTest A/pom.xml. Mais si je retire la <version>0.1-SNAPSHOT</version>de B/pom.xmlla rubrique mère, se plaint maven sur la version manquante pour le parent.

Y a-t-il un moyen que je puisse simplement utiliser ${project.version}ou quelque chose comme ça pour éviter d'avoir 01.-SNAPSHOTdans les deux poms?

Shengjie
la source
4
Vous devrez attendre Maven 3.1 pour cela, j'en ai peur.
Perception
1
Le lien ci-dessus a été déplacé. Le statut final était "Closed / Won't Fix" issues.apache.org/jira/browse/MNG-624
jocull

Réponses:

87

EDIT: Depuis Maven 3.5.0, il existe une bonne solution pour cela en utilisant un ${revision}espace réservé. Voir la réponse de FrVaBe pour plus de détails. Pour les versions précédentes de Maven, voir ma réponse originale ci-dessous.


Non, il n'y en a pas. Vous devez toujours spécifier la version du parent. Heureusement, il est hérité comme version du module ce qui est souhaitable dans la plupart des cas. De plus, la déclaration de version de ce parent est automatiquement annulée par Maven Release Plugin, donc - en fait - ce n'est pas un problème que vous ayez une version à 2 endroits tant que vous utilisez Maven Release Plugin pour publier ou simplement modifier des versions.

Notez qu'il existe certains cas où ce comportement est en fait assez correct et donne plus de flexibilité dont vous pourriez avoir besoin. Parfois, vous souhaitez utiliser une partie de la version précédente du parent pour hériter, mais ce n'est pas un cas courant.

Michał Kalinowski
la source
3
Nowadys vous pouvez utiliser l' ${revision}espace réservé pour cela. Voir ma réponse ;-)
FrVaBe
2
Ceci est maintenant obsolète - vérifiez la réponse de @ FrVaBe ici: stackoverflow.com/a/51969067/514483
robd
@FrVaBe et si nous avons des parents imbriqués avec des versions différentes? On ne peut pas y utiliser une seule propriété $ {revision}, ce n'est pas suffisant.
halil
@halil La question concerne l'héritage d'une version d'un parent dans le but d'avoir la même version dans deux artefacts. Si vous avez différents parents avec des versions différentes (dans une hiérarchie d'héritage), vous ne les rendrez probablement pas tous de la même version. Je ne comprends donc pas entièrement le commentaire.
FrVaBe
86

Maven n'est pas conçu pour fonctionner de cette façon, mais une solution de contournement existe pour atteindre cet objectif (peut-être avec des effets secondaires, vous devrez essayer). L'astuce consiste à dire au projet enfant de trouver son parent via son chemin relatif plutôt que ses coordonnées maven pures, et en plus d'externaliser le numéro de version dans une propriété:

Pom parent

<groupId>com.dummy.bla</groupId>
<artifactId>parent</artifactId>
<version>${global.version}</version>
<packaging>pom</packaging>

<properties>
   <!-- Unique entry point for version number management --> 
   <global.version>0.1-SNAPSHOT</global.version>
</properties>

Enfant pom

<parent>
   <groupId>com.dummy.bla</groupId>
   <artifactId>parent</artifactId>
   <version>${global.version}</version>
   <relativePath>..</relativePath>    
</parent>

<groupId>com.dummy.bla.sub</groupId>
<artifactId>kid</artifactId>

J'ai utilisé cette astuce pendant un moment pour l'un de mes projets, sans problème spécifique, sauf le fait que maven enregistre beaucoup d'avertissements au début de la construction, ce qui n'est pas très élégant.

ÉDITER

Il semble que maven 3.0.4 n'autorise plus une telle configuration.

Yanflea
la source
2
oui, j'ai peur que maven ne soit pas conçu pour fonctionner de cette façon, mieux vaut simplement s'en tenir à mettre les versions dans le sous pom.xml. Le plugin maven release ne se soucie pas vraiment des versions là-bas de toute façon.
Shengjie
7
pour 3.0.5 fonctionne bien. vous devriez mettre <properties> tout en haut.
ses
7
Cela fonctionne en 3.2.3. L'emplacement de <properties> n'a pas d'importance. Vous recevrez un avertissement cependant:'version' contains an expression but should be a constant.
kapex
4
S'il vous plaît, soyez prudent avec cela. Cela ne fonctionne pas lorsque votre projet est référencé par un autre projet. La propriété ne sera pas résolue et sera traitée littéralement (c'est-à-dire $ {ma.version}). Cela entraînera un échec lors de la résolution des dépendances.
spekdrum
2
Je l'utilise également depuis un certain temps maintenant et cela fonctionne très bien (actuellement avec maven 3.3.9) pour un seul projet multi-module. Cependant, dès que votre projet devient une dépendance d'un autre projet, les choses deviennent vraiment délicates. Je suggère vraiment d'adopter la suggestion proposée par @pay ci-dessous.
ingénieux
82

Le moyen le plus simple de mettre à jour les versions IMO:

$ mvn versions:set -DgenerateBackupPoms=false

(faites cela dans votre dossier pom racine / parent).

Vos POM sont analysés et il vous est demandé quelle version définir.

Pai
la source
17
Vous pouvez également ajouter -DnewVersion = {versionToBeUpdated} pour éviter de le saisir de manière interactive.
Mukesh
1
Je pense que c'est la meilleure réponse, elle automatise les changements de version sans casser les sous-projets (auxquels vous ne pourriez pas faire référence sans le pom parent).
Tarek le
Ouaip! Voilà la réponse. 🙌
aaiezza
Si les versions enfant et parent de pom sont initialement différentes, mettez-les d'abord à jour pour qu'elles correspondent, mvn versions:update-child-modules sinon toutes les versions de pom du module enfant seront ignorées.
Gautam Tadigoppula
81

Depuis Maven 3.5.0, vous pouvez utiliser l' ${revision}espace réservé pour cela. L'utilisation est documentée ici: Versions Maven CI Friendly .

En bref, le pom parent ressemble à ceci (cité dans la documentation Apache):

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache</groupId>
    <artifactId>apache</artifactId>
    <version>18</version>
  </parent>
  <groupId>org.apache.maven.ci</groupId>
  <artifactId>ci-parent</artifactId>
  <name>First CI Friendly</name>
  <version>${revision}</version>
  ...
  <properties>
    <revision>1.0.0-SNAPSHOT</revision>
  </properties>
  <modules>
    <module>child1</module>
    ..
  </modules>
</project>

et l'enfant pom comme ça

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache.maven.ci</groupId>
    <artifactId>ci-parent</artifactId>
    <version>${revision}</version>
  </parent>
  <groupId>org.apache.maven.ci</groupId>
  <artifactId>ci-child</artifactId>
   ...
</project>

Vous aussi devez utiliser le Aplatir Maven Plugin pour générer des documents pom avec le numéro de version dédiée inclus pour le déploiement. Le HowTo est documenté dans la documentation liée.

@Khmarbaise a également écrit un joli article sur cette fonctionnalité: Maven: Fichiers POM sans version?

FrVaBe
la source
1
J'ai configuré mon projet comme vous l'avez décrit, mais sans le "Flatten Maven Plugin" et il semble fonctionner comme prévu, est-ce possible? J'ai également eu une erreur avec maven 3.2.1, mais maven 3.3.9+ semble fonctionner correctement.
maxeh
1
@Max Cela dépend de ce que vous définissez comme "travailler comme prévu". Je suppose que la construction passera mais installer / déployer sur un référentiel ne sera probablement pas une bonne idée car il n'y a pas de numéro de version dans le pom enfant mais seulement un espace réservé (voir documentation )
FrVaBe
J'utilise <version> $ {revision} </version> dans le pom parent avec la propriété par défaut (<properties> <version> 0.1-default </version> </properties>. Les enfants poms utilisent également <version> $ {revision} < / version>. J'utilise "mvn clean install -Drevision = 0.1. $ {bamboo.buildNumber}". Lorsque j'analyse les journaux du déploiement, tout est réglé sur 0,1.820 et 0,1-par défaut n'est même pas dans les journaux (820 est le buildNumber). Lorsque je scanne le fichier jar résultant, je vois "Implementation-Version: 0.1.820" dans le manifeste, ainsi que "version = 0.1.820" dans un fichier pom.properties. Le fichier pom lui-même a <version> $ {revision} </version>. Donc je pense que ça va?
maxeh
1
@Max Essayez de résoudre un fichier jar où la version est ${revision} dans le pom (dans le référentiel maven) en tant que dépendance dans un autre projet. Je ne pense pas que cela fonctionnera.
FrVaBe
1
@Ralf J'ai arrêté de penser que les gammes de versions étaient une bonne idée il y a des années. Vous ne pouvez pas obtenir une version reproductible avec. Donc je ne les utilise plus.
FrVaBe
21

Comme Yanflea l'a mentionné, il existe un moyen de contourner cela.

Dans Maven 3.5.0, vous pouvez utiliser la méthode suivante pour transférer la version du projet parent:

Parent POM.xml

<project ...>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mydomain</groupId>
    <artifactId>myprojectparent</artifactId>
    <packaging>pom</packaging>
    <version>${myversion}</version>
    <name>MyProjectParent</name>

    <properties>
        <myversion>0.1-SNAPSHOT</myversion>
    </properties>

    <modules>
        <module>modulefolder</module>
    </modules>
    ...
</project>

Module POM.xml

<project ...>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.mydomain</groupId>
        <artifactId>myprojectmodule</artifactId>
        <version>${myversion}</version> <!-- This still needs to be set, but you can use properties from parent -->
    </parent>

    <groupId>se.car_o_liner</groupId>
    <artifactId>vinno</artifactId>
    <packaging>war</packaging>
    <name>Vinno</name>
    <!-- Note that there's no version specified; it's inherited from parent -->
    ...
</project>

Vous êtes libre de changer myversionpour ce que vous voulez qui n'est pas une propriété réservée.

eFox
la source
3
Lors du référencement d'un module d'un autre projet, Maven ne résout pas la propriété. Est-ce normal?
LeoLozes
Je pense que cette question mérite peut-être sa propre entrée et ne doit pas figurer dans un commentaire de ce genre. Sans voir votre code, je ne peux que le deviner.
eFox le
@LeoLozes Avez-vous résolu votre problème (module de réfraction d'un autre projet)?
Morteza Malvandi
@MortezaMalvandi oui! Ma réponse est en bas :)
LeoLozes
3
Maven 3.6.0 donne un avertissement pour cette configuration: "Il est fortement recommandé de résoudre ces problèmes car ils menacent la stabilité de votre build." "Pour cette raison, les futures versions de Maven pourraient ne plus prendre en charge la construction de tels projets mal formés."
d2k2
18

Vous pouvez également utiliser:

$ mvn release:update-versions -DdevelopmentVersion={version}

pour mettre à jour les numéros de version dans vos POM.

Jerry Jin
la source
11

La réponse d' eFox a fonctionné pour un seul projet, mais pas lorsque je référençais un module d'un autre (le pom.xml était toujours stocké dans my .m2avec la propriété au lieu de la version).

Cependant, cela fonctionne si vous le combinez avec le flatten-maven-plugin, car il génère les poms avec la version correcte, pas la propriété.

La seule option que j'ai modifiée dans la définition du plug-in est la outputDirectory, elle est vide par défaut, mais je préfère l'avoir dans target, qui est définie dans ma .gitignoreconfiguration:

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>flatten-maven-plugin</artifactId>
   <version>1.0.1</version>
   <configuration>
      <updatePomFile>true</updatePomFile>
      <outputDirectory>target</outputDirectory>
   </configuration>
   <executions>
      <execution>
         <id>flatten</id>
         <phase>process-resources</phase>
         <goals>
            <goal>flatten</goal>
         </goals>
      </execution>
   </executions>
</plugin>

La configuration du plug-in va dans le pom.xml parent

LeoLozes
la source
0
<parent>
    <groupId>com.dummy.bla</groupId>
    <artifactId>parent</artifactId>
    <version>0.1-SNAPSHOT</version>     
 </parent>

 <groupId>com.dummy.bla.sub</groupId>
 <artifactId>kid</artifactId>

Vous voulez dire que vous voulez supprimer la version du bloc parent du pom de B, je pense que vous ne pouvez pas le faire, le groupId, artifactId et la version ont spécifié les coordonnées pom du parent, ce que vous pouvez omettre est la version de l'enfant.

Yu Chai
la source