DependencyManagement and Dependencies in Maven

Summary

In this post, I will introduce the key difference between Maven’s <dependencyManagement> and <dependencies>.

Conclusion

  1. In pom inheritance, artifacts specified <dependencies> will ALWAYS be included as a dependency of the child module(s). However, artifacts specified in <dependencyManagement> will only be included if child modules explicitly specify them in <dependencies>.
  2. <dependencyManagement> is good for centralized version control.
  3. <dependencyManagement> is good for import managed dependencies from other projects.

Details

We are always curious to dive deeper and examples are more intuitive than theory. We build a parent pom and a child pom to explain the above conclusions. We install the parent pom into local repo by sudo mvn clean install.

<!--  Parent pom  -->
    <groupId>edu.fighternan.java</groupId>
    <artifactId>review</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <dependencies>
        <dependency>
            <artifactId>lambda</artifactId>
            <groupId>software.amazon.awssdk</groupId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.3.9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
<!--  Child pom  -->
    <parent>
        <groupId>edu.fighternan.java</groupId>
        <artifactId>review</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>edu.fighternan.java</groupId>
    <artifactId>review2</artifactId>
    <version>1.0-SNAPSHOT</version>

1. Inheritance

The parent pom imports another <dependencyManagement>, which will be explained later. What we know for now is that the parent pom specifies a dependency explicitly.

By execute mvn dependency:tree, we can see the denpendency tree.

[INFO] edu.fighternan.java:review:pom:1.0-SNAPSHOT [INFO] \- software.amazon.awssdk:lambda:jar:2.3.9:compile

In the child pom, we do not have any explicit dependencies. However, it has a transitive dependency inherited from its parent.

[INFO] edu.fighternan.java:review2:jar:1.0-SNAPSHOT [INFO] \- software.amazon.awssdk:lambda:jar:2.3.9:compile

If we remove the explicit dependency in parent pom by removing the whole <dependencies> element. There will be no dependencies for both parent and child anymore.

2. Centralized Version Control

In the parent pom, we explicitly declare a AWS lambda artifact without version. Actually software.amazon.awssdk.aws-sdk-java-pom which is the parent of software.amazon.awssdk.bom defines the version. BOM stands for bill of materials, which centralizes the version control for any other artifact which imports the BOM.

3. Multiple Inheritance

You cannot have a pom-type project as a simple dependency in another project. There can only be a parent-child relationship. However, a project can only inherit from a single parent.

Import scope for pom type dependency in <dependencyManagement> section allows you to achieve the equivalent of multiple inheritances. Also, you can leverage the centralized control of <dependencyManagement>.

Reference

Maven’s Official Guide

Leave a Reply

Your email address will not be published. Required fields are marked *