Centralizing Dependency Versions with Maven's <dependencyManagement> in Parent POMs
Learn how to use Maven's <dependencyManagement> in a parent POM to enforce consistent versions across modules and avoid mismatched dependencies.
26 Jul 2025, 19:47 UTC

The Quick Takeaway
\nIf you maintain a multi‑module Maven project, declare the versions you want in a parent POM’s <dependencyManagement> section; child modules then inherit the version automatically and avoid version drift.
How It Works
\nMaven treats <dependencyManagement> as a catalog of coordinates and versions. The catalog is not added to the classpath; it only supplies a version when a child module declares the same coordinates without a <version>. For example, a parent POM may contain:
<dependencyManagement>\n <dependencies>\n <dependency>\n <groupId>org.apache.maven.plugins</groupId>\n <artifactId>maven-compiler-plugin</artifactId>\n <version>3.11.0</version>\n </dependency>\n </dependencies>\n</dependencyManagement>\nIn a child module, you can then write:
\n<dependency>\n <groupId>org.apache.maven.plugins</groupId>\n <artifactId>maven-compiler-plugin</artifactId>\n <!-- no version, Maven will use the managed version -->\n</dependency>\nWhen you run mvn dependency:tree in the child module, Maven will show the version coming from the parent’s <dependencyManagement> and will not list an explicit version in the child’s POM.
Verification Steps
\n- \n
- Open a terminal in any child module directory. \n
- Run
mvn dependency:tree | grep <artifactId>to confirm the managed version appears. \n - Execute
mvn help:effective-pomand inspect the<dependencies>section; the managed entry should be present. \n - Change the version in the parent’s
<dependencyManagement>(e.g., to 3.12.0) and re‑runmvn clean install. All modules should now compile against the new version without any POM edits. \n
Limits and Common Mistakes
\n- \n
- Declaration does not add the dependency. The child POM must still list the dependency; otherwise the artifact will not be on the classpath. \n
- Explicit versions in child POMs override management. If a child also specifies
<version>, Maven selects the nearest declaration, which can cause unexpected conflicts. \n - Reactor inconsistency. Changing the parent POM’s
<dependencyManagement>forces a full reactor rebuild; modules that still reference an older parent version may resolve against stale artifacts. \n - Transitive dependency mediation.
<dependencyManagement>does not automatically constrain transitive dependencies; you must manage those separately if version uniformity is required. \n
To detect mismatches, run mvn help:effective-pom on a child module and compare the <version> value for the managed dependency with the version declared in the parent POM. Any discrepancy indicates either an explicit version in the child or an outdated parent.
Practical verification checklist:
\n- \n
- Parent POM contains
<dependencyManagement>entries for all versions you want to enforce. \n - Each child module lists the corresponding dependencies without a
<version>attribute. \n - Running
mvn dependency:treein any child shows the managed version and no explicit version in the child’s POM. \n - Updating a version in the parent and rebuilding the whole reactor confirms that all modules adopt the change automatically. \n
By centralizing version declarations, you reduce the risk of “dependency hell” across modules, simplify upgrades, and keep builds reproducible. However, remember that <dependencyManagement> is only a version catalog; it does not inject artifacts, and it does not override transitive versions unless you manage them explicitly. Use the verification steps above to ensure the intended behavior is in place before committing changes.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.