Summary
In this post, I will introduce the key difference between Maven’s <dependencyManagement> and <dependencies>.
Conclusion
- 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>. <dependencyManagement>is good for centralized version control.<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>.