On this page
Maven Dependencies
Maven’s dependency management automatically resolves transitive dependencies and ensures consistent versions across a project.
Declaring Dependencies
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.0.0-jre</version>
</dependency>
</dependencies>
Dependency Scopes
| Scope | Compile | Test | Runtime | Example |
|---|---|---|---|---|
compile (default) |
✓ | ✓ | ✓ | Guava, Spring |
test |
✓ | JUnit, Mockito | ||
runtime |
✓ | ✓ | JDBC driver | |
provided |
✓ | ✓ | Servlet API (container provides) | |
system |
✓ | ✓ | Local JAR (avoid) | |
import |
BOM import only |
Transitive Dependencies
Maven resolves dependencies recursively. If A depends on B, and B depends on C, your project gets C automatically:
my-app → spring-boot-starter-web → spring-web → spring-core
View the tree:
mvn dependency:tree
mvn dependency:tree -Dincludes=com.google.guava
Exclusions
Remove unwanted transitive dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
Dependency Management (BOM)
Centralize version control without adding dependencies:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Now declare without version -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Version Conflicts
When two dependencies require different versions of the same artifact, Maven uses nearest definition (shortest path in the tree).
Force a specific version:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.0.0-jre</version>
</dependency>
</dependencies>
</dependencyManagement>
Best Practices
- Use BOM/
dependencyManagementto control versions centrally - Prefer
testscope for test-only libraries - Run
mvn dependency:treeto diagnose conflicts - Avoid
systemscope — use a proper repository instead - Keep dependencies minimal — remove unused ones regularly