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

InheritanceMaven

Inheritance Problem Overview


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?

Inheritance Solutions


Solution 1 - Inheritance

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?

Solution 2 - Inheritance

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.

Solution 3 - Inheritance

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.

Solution 4 - Inheritance

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.

Solution 5 - Inheritance

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.

Solution 6 - Inheritance

You could also use:

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

to update the version numbers in your POMs.

Solution 7 - Inheritance

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

Solution 8 - Inheritance

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

Solution 9 - Inheritance

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

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

You mean you want to remove the version from parent block of B's pom, I think you can not do it, the groupId, artifactId, and version specified the parent's pom coordinate's, what you can omit is child's version.

Solution 10 - Inheritance

It worked for me using BOM approach on parent pom.xml: 

My scenario:
 - parent pom.xml 0.0.0.1-SNAPSHOT
 - sub-project1
 - sub-project2 (sub-project1 is a dependency)

<properties>        
    <revision>0.0.0.1-SNAPSHOT</revision>        
</properties>

<groupId>com.example</groupId>
<artifactId>commons</artifactId>
<packaging>pom</packaging>
<version>${revision}</version>
<name>commons</name>
<description>parent module of commons project</description>


<modules>
    <module>sub-project1</module>
    <module>sub-project2</module>
</modules>

<dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <type>pom</type>
            <version>2.6.4</version>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>com.example.commons</groupId>
            <artifactId>sub-project1</artifactId>
            <version>${revision}</version>
        </dependency>
    </dependencies>

</dependencyManagement>

The sub-project pom.xml can inherit ${revision} number from parent and also the actual listed dependency doesn't need to have tag explicitly mentioned

    <parent>
		<groupId>com.example</groupId>
		<artifactId>commons</artifactId>
		<version>${revision}</version>
		<relativePath>../pom.xml</relativePath>
	</parent>

	<groupId>com.example.commons</groupId>
	<artifactId>sub-project2</artifactId>
	<version>${revision}</version>
	<name>sub-project2</name>
	<description>implement sub-project2 </description>

	
	<dependencies>	
		<dependency>
			<groupId>com.example.commons</groupId>
			<artifactId>sub-project1</artifactId>			
		</dependency>
       
    </dependencies>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShengjieView Question on Stackoverflow
Solution 1 - InheritanceFrVaBeView Answer on Stackoverflow
Solution 2 - InheritanceMichał KalinowskiView Answer on Stackoverflow
Solution 3 - InheritanceYanfleaView Answer on Stackoverflow
Solution 4 - InheritancepaiView Answer on Stackoverflow
Solution 5 - InheritanceeFoxView Answer on Stackoverflow
Solution 6 - InheritanceJerry JinView Answer on Stackoverflow
Solution 7 - InheritanceLeoLozesView Answer on Stackoverflow
Solution 8 - InheritanceHleb TurchykView Answer on Stackoverflow
Solution 9 - InheritanceYu ChaiView Answer on Stackoverflow
Solution 10 - InheritanceAjay VView Answer on Stackoverflow