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>
.