Why the maven child referencing versions from BOM does not work?

I created this example POM file so that I do not need the dependency versions replicated in each child project. My requirement is that the thirdparty version need not be provided for each project. Each project should inherit the library versions from the bom file. I created the example based on the documentation of Maven dependencies. My maven version is Apache Maven 3.2.5

I am getting the error below

[INFO] Scanning for projects...
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]   
[ERROR]   The project org.test.testapp:test-app:1.0-SNAPSHOT (/Users/skoya/workspace/test-app/pom.xml) has 2 errors
[ERROR]     'dependencies.dependency.version' for junit:junit:jar is missing. @ line 22, column 17
[ERROR]     'dependencies.dependency.version' for commons-cli:commons-cli:jar is missing. @ line 26, column 17

root bom pom file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <groupId>org.test</groupId>
        <artifactId>bom</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>pom</packaging>
        <name>test-dependencies-bom</name>
        <url>http://myorg.org</url>

        <properties>
                <commons-cli.version>1.3</commons-cli.version>
                <junit.version>3.8.1</junit.version>
        </properties>

        <modules>
            <module>test-dependencies</module>
        </modules>
</project>

test-dependencies/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <groupId>org.test</groupId>
        <artifactId>test-parent-pom</artifactId>  
        <version>0.0.1-SNAPSHOT</version>
        <packaging>pom</packaging>

        <name>test-parent-pom</name>
        <url>http://maven.apache.org</url>
        <parent>
                <groupId>org.test</groupId>
                <artifactId>bom</artifactId>
                <version>0.0.1-SNAPSHOT</version>
        </parent>

        <prerequisites>
                <maven>3.0.0</maven>
        </prerequisites>


        <dependencies>
                <dependency>
                        <groupId>commons-cli</groupId>
                        <artifactId>commons-cli</artifactId>
                        <version>${commons-cli.version}</version>
                </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
                        <version>${junit.version}</version>
    </dependency>

        </dependencies> 
</project>

Maven project files referencing the bom file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.test.testapp</groupId>
  <artifactId>test-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>test-app</name>
  <url>http://maven.apache.org</url>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.test</groupId>
        <artifactId>bom</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
    <dependency>
      <groupId>commons-cli</groupId>
      <artifactId>commons-cli</artifactId>
    </dependency>
  </dependencies>
</project>

Upvotes: 3

Views: 6462

Answers (1)

Chris Nauroth
Chris Nauroth

Reputation: 9844

There are 2 issues:

  1. For importing of dependencies, the imported pom project (test-dependencies/pom.xml) should define the dependencies to import in a <dependencyManagement> section, not just <dependencies> as was done in your original sample.
  2. The project that imports that pom needs to import the project that declares the dependencies (test-dependencies/pom.xml), not the parent pom.xml.

I fixed this by making the following changes.

test-dependencies/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.test</groupId>
  <artifactId>test-parent-pom</artifactId>  
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>test-parent-pom</name>
  <url>http://maven.apache.org</url>

  <parent>
    <groupId>org.test</groupId>
    <artifactId>bom</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>

  <prerequisites>
    <maven>3.0.0</maven>
  </prerequisites>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>commons-cli</groupId>
        <artifactId>commons-cli</artifactId>
        <version>${commons-cli.version}</version>
      </dependency>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

Maven project files referencing the bom file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.test.testapp</groupId>
  <artifactId>test-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>test-app</name>
  <url>http://maven.apache.org</url>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.test</groupId>
        <artifactId>test-parent-pom</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
    <dependency>
      <groupId>commons-cli</groupId>
      <artifactId>commons-cli</artifactId>
    </dependency>
  </dependencies>
</project>

After that, I was able to build and verify that the project importing the pom was bringing in the expected dependencies:

mvn dependency:tree
...
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ test-app ---
[INFO] org.test.testapp:test-app:jar:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:3.8.1:compile
[INFO] \- commons-cli:commons-cli:jar:1.3:compile

Note that it still successfully pulled the version numbers as defined in properties from the parent pom.xml. This a perfectly valid way to structure the project. It just needed the 2 adjustments I described.

Upvotes: 5

Related Questions