Fork me on GitHub

Defining versions of multiple modules in a central place

Various projects have a multi-module setup but typically want dependencies between modules of the same project to use the recent version. With flatten-maven-plugin you can define the versions in a single place.

Top-level POM

In your top-level POM set a fixed version ("dev"), add flatten-maven-plugin and define variables for the versions of your modules:
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.whizbang</groupId>
  <artifactId>whizbang</artifactId>
  <version>dev</version>
  <packaging>pom</packaging>
  <properties>
    <whizbang.module1.version>3.1.7-SP2<whizbang.module1.version>
    <whizbang.module2.version>1.4.1-GA<whizbang.module2.version>
    ...
  </properties>
  <modules>
    <module>whizbang-module1</module>
    <module>whizbang-module2</module>
    ...
  </modules>
  <build>
    <plugins>
      ...
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>flatten-maven-plugin</artifactId>
        <!--<version>1.0.1</version>-->
        <configuration>
        </configuration>
        <executions>
          <execution>
            <id>flatten</id>
            <phase>process-resources</phase>
            <goals>
              <goal>flatten</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <dependencyManagement>
    <dependencies>
      <!-- Internal dependencies -->
      <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>whizbang-module1</artifactId>
        <version>${whizbang.module1.version}</version>
      </dependency>
      <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>whizbang-module2</artifactId>
        <version>${whizbang.module2.version}</version>
      </dependency>
      <!-- External dependencies -->
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
      </dependency>
      <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>      
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>
        

Leaf POM

In your leaf POM (child with packaging other than pom) you inherit the parent and use the corresponding version variable:
<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.example.whizbang</groupId>
    <artifactId>whizbang</artifactId>
    <version>dev</version>
  </parent>
  <artifactId>whizbang-module1</artifactId>
  <version>${whizbang.module1.version}</version>
  <packaging>jar</packaging>
  <dependencies>
    <!-- Internal dependencies with managed version -->
    <dependency>
      <groupId>com.example.whizbang</groupId>
      <artifactId>whizbang-module2</artifactId>
    </dependency>

    <!-- External dependencies with managed version -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
        
If you install or deploy the project the flattened POM of whizbang-module1 that goes into the repository will look like this:
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.whizbang</groupId>
  <artifactId>whizbang-module1</artifactId>
  <version>3.1.7-SP2</version>
  <packaging>jar</packaging>
  <dependencies>
    <dependency>
      <groupId>com.example.whizbang</groupId>
      <artifactId>whizbang-module2</artifactId>
      <version>1.4.1-GA</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>      
    </dependency>
  </dependencies>
</project>