Unified Maven Dependency Management for Multi‑Module Java Projects
This article explains how Java developers can use Maven’s dependency‑management features to create a centralized version‑control system that unifies third‑party library versions across multiple modules and services, reducing upgrade pain, avoiding version conflicts, and establishing a solid foundation for scalable backend architecture.
This article, originally published on the Juejin technical community, targets junior Java developers who spend most of their time writing CRUD code for business features and often lack a systematic technical foundation.
The author observes that in small companies developers may occasionally touch low‑level components, while large companies provide scaffolding and SDKs that make business development straightforward, leading to stagnant technical growth over the years.
To break this stagnation, the author launches a series of columns describing how to build a foundational infrastructure from scratch.
"I originally wanted to give up this column and write a small booklet, but I signed a contract, so I’m pushing forward."
1. Chaotic Version Dependencies
Many small‑to‑medium companies promote "agile development" and quickly adopt popular open‑source libraries such as hutool , fastjson , and easyexcel . These libraries are usually added via Maven dependencies, but their popularity also means frequent security vulnerabilities.
For example, FastJSON has had remote‑code‑execution vulnerabilities, and the Log4j bug caused massive upgrade effort across micro‑service architectures.
When a tool library releases a critical fix, upgrading each service individually becomes painful, especially when multiple services depend on the same component.
Therefore, establishing a unified version‑dependency system is essential.
2. Maven Dependency Priority
Before designing a unified system, it is important to understand Maven’s conflict‑resolution rules.
2.1 Shortest Path Wins
If a project directly depends on C‑2.0 and also pulls in C‑1.0 through B , Maven selects C‑2.0 because the path Project → C‑2.0 is shorter than Project → B → C‑1.0 .
2.2 pom Declaration Order Wins
When two paths have equal length (e.g., Project → B → C‑1.0 and Project → D → C‑2.0 ), Maven respects the order of dependency entries in the pom.xml . The later declaration overrides the earlier one.
3. Maven Package Version Control
In a multi‑module Spring project, many modules may need the same library (e.g., FastJSON). Two approaches are discussed:
3.1 Manual Convention
Each module adds the same dependency with an explicit version, but this relies on every developer following the rule, which is error‑prone.
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.43</version>
</dependency>3.2 Using dependencyManagement
Define the version once in the parent pom’s dependencyManagement section, then child modules can declare the dependency without a version, inheriting the centralized definition.
<dependencyManagement>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.43</version>
</dependency>
</dependencyManagement> <dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>4. Top‑Level Version Management
Spring Boot’s parent pom ( spring-boot-starter-parent ) already defines a comprehensive set of dependency versions. By inheriting this parent, all Spring‑related jars share consistent versions, and upgrading a single parent version updates the whole ecosystem.
5. Multi‑Project Global Management
Inspired by Spring Boot’s approach, the author proposes creating a dedicated Maven project (e.g., baiyan-common-dependency ) that serves as the top‑level version‑management module for business‑specific libraries such as MySQL drivers, FastJSON, etc.
├── pom.xml
└── baiyan-common-dependency.imlKey steps:
Set the new project’s parent to spring-boot-starter-parent .
Declare common third‑party versions in its dependencyManagement .
Publish the project to a private Maven repository (or install locally for testing).
Replace the default Spring Boot parent in business services with this custom parent.
If a service needs a different version (e.g., spring-boot-web 2.3.8.RELEASE vs. the managed 2.3.10.RELEASE ), the service can override the version in its own dependencyManagement because Maven’s shortest‑path rule gives precedence to the direct declaration.
6. Summary
The article demonstrates how to use Maven to centralize and unify third‑party library versions across multiple modules and services, laying the groundwork for a maintainable backend infrastructure. It outlines best practices: create a top‑level version‑management project, replace the default Spring Boot parent with it, and use dependencyManagement to enforce consistent versions while allowing selective overrides.
Key takeaways:
Define a top‑level Maven version‑management module containing common tool and component versions.
Replace the default Spring Boot parent in business services with the custom module.
For modules that need independent versions, declare them in the service’s own dependencyManagement section.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.