Maven project version inheritance - do I have to specify the parent version?


Translate

I have two projects: Parent project: A, Sub project: B

A/pom.xml:

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

And in B/pom.xml, I have:

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

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

I want B to inherit the version from parent, so the only place in my case I need to put 0.1-SNAPSHOT is A/pom.xml. But if i remove the <version>0.1-SNAPSHOT</version> from B/pom.xml under the parent section, maven complains about the missing version for the parent.

Is there a way I can just use ${project.version} or something like this to avoid having 01.-SNAPSHOT in both poms?


All Answers
  • Translate

    EDIT: Since Maven 3.5.0 there is a nice solution for this using ${revision} placeholder. See FrVaBe's answer for details. For previous Maven versions see my original answer below.


    No, there isn't. You always have to specify parent's version. Fortunately, it is inherited as the module's version what is desirable in most cases. Moreover, this parent's version declaration is bumped automatically by Maven Release Plugin, so - in fact - it's not a problem that you have version in 2 places as long as you use Maven Release Plugin for releasing or just bumping versions.

    Notice that there are some cases when this behaviour is actually pretty OK and gives more flexibility you may need. Sometimes you want to use some of previous parent's version to inherit, however that's not a mainstream case.


  • Translate

    Maven is not designed to work that way, but a workaround exists to achieve this goal (maybe with side effects, you will have to give a try). The trick is to tell the child project to find its parent via its relative path rather than its pure maven coordinates, and in addition to externalize the version number in a property :

    Parent pom

    <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>
    

    Child 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>
    

    I used that trick for a while for one of my project, with no specific problem, except the fact that maven logs a lot of warnings at the beginning of the build, which is not very elegant.

    EDIT

    Seems maven 3.0.4 does not allow such a configuration anymore.


  • Translate

    The easiest way to update versions IMO:

    $ mvn versions:set -DgenerateBackupPoms=false
    

    (do that in your root/parent pom folder).

    Your POMs are parsed and you're asked which version to set.


  • Translate

    Since Maven 3.5.0 you can use the ${revision} placeholder for that. The use is documented here: Maven CI Friendly Versions.

    In short the parent pom looks like this (quoted from the Apache documentation):

    <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>
    

    and the child pom like this

    <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>
    

    You also have to use the Flatten Maven Plugin to generate pom documents with the dedicated version number included for deployment. The HowTo is documented in the linked documentation.

    Also @khmarbaise wrote a nice blob post about this feature: Maven: POM Files Without a Version in It?


  • Translate

    As Yanflea mentioned, there is a way to go around this.

    In Maven 3.5.0 you can use the following way of transferring the version down from the parent project:

    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>
    

    You are free to change myversion to whatever you want that isn't a reserved property.


  • Translate

    You could also use:

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

    to update the version numbers in your POMs.


  • Translate

    eFox's answer worked for a single project, but not when I was referencing a module from another one (the pom.xml were still stored in my .m2 with the property instead of the version).

    However, it works if you combine it with the flatten-maven-plugin, since it generates the poms with the correct version, not the property.

    The only option I changed in the plug-in definition is the outputDirectory, it's empty by default, but I prefer to have it in target, which is set in my .gitignore configuration:

    <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>
    

    The plug-in configuration goes in the parent pom.xml


  • Translate

    Use mvn -N versions:update-child-modules to update child pom`s version

    https://www.mojohaus.org/versions-maven-plugin/examples/update-child-modules.html