The pom.xml Dependencies Section
Fast recall
Quick revision
Core answer
dependencies section declares artifacts needed on one or more project classpaths. Each entry has groupId and artifactId, usually a version supplied directly or by dependencyManagement, plus optional type, classifier, scope, exclusions, and optionality. Maven resolves transitive dependencies according to scope and conflict rules; archive contents are controlled separately by packaging plugins.Practical understanding of Maven dependency management — adding and troubleshooting dependencies is a daily task for Java developers
Not understanding the difference between dependencies and dependencyManagement — the former pulls in libraries, the latter only declares versions
Explain Maven's transitive dependency resolution and how you can use mvn dependency:tree to debug dependency conflicts
Interview-ready guide
Interview answer
The dependencies section is where you list all the external libraries your project needs.
Each dependency is identified by its Maven coordinates — groupId, artifactId, and version.
For example, if you need Spring Web to build REST APIs, you add spring-boot-starter-web with its groupId and artifactId. Maven then downloads that library from Maven Central or other configured repositories and puts it on your classpath. The magic of Maven is it handles transitive dependencies automatically.
If spring-boot-starter-web depends on Jackson for JSON processing and Tomcat for the web server, Maven downloads those too without you specifying them. You can see the full dependency tree by running mvn dependency:tree. One important detail is the scope attribute.
The default is compile, which means the dependency is available everywhere — during compilation, testing, and runtime. But you should use test scope for testing libraries so they stay on test classpaths. Use runtime scope for database drivers since you only need them at runtime, not compile time.
When you're using spring-boot-starter-parent, you can omit the version element for Spring Boot managed dependencies. The parent POM provides those versions through its dependency management section. One mistake freshers make is confusing dependencies with dependencyManagement.
The management section only declares versions without pulling in libraries. You still need to list the dependency in the dependencies section to actually use it.
The pom.xml Dependencies Section
Direct Answer
The POM's dependencies section declares artifacts needed on one or more project classpaths. Each entry has groupId and artifactId, usually a version supplied directly or by dependencyManagement, plus optional type, classifier, scope, exclusions, and optionality. Maven resolves transitive dependencies according to scope and conflict rules; archive contents are controlled separately by packaging plugins.
Code Example
<dependencies>
<!-- Web starter: Spring MVC, Tomcat, JSON processing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- Version inherited from spring-boot-starter-parent -->
</dependency>
<!-- JPA starter: Hibernate, Spring Data JPA, JDBC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- PostgreSQL JDBC driver: runtime scope -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope> <!-- Only needed at runtime, not compile -->
</dependency>
<!-- Test dependencies: JUnit 5, Mockito, Spring Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <!-- Only on test classpath -->
</dependency>
<!-- Non-Spring dependency with explicit version -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version> <!-- Not managed by parent -->
</dependency>
</dependencies>
Common Mistakes & Pitfalls
- Confusing dependencies with dependencyManagement: Freshers add dependencies to the dependencyManagement section expecting them to be available in their code, but dependencyManagement only declares versions without pulling in the libraries. You must still declare the dependency in the dependencies section to actually use it.
- Forgetting scope for test dependencies: Adding JUnit or Mockito without scope test means those libraries enter the production dependency graph unnecessarily.
- Hardcoding versions when using starter parent: Specifying explicit versions for Spring Boot managed dependencies can create conflicts — let the parent POM manage versions unless you have a specific reason to override.
- Not understanding transitive dependencies: Getting confused when a library appears in your classpath even though you didn't declare it — this is Maven's transitive dependency feature working as designed, not a bug.
Check your understanding
Answer these without looking back at the article.
- What is dependency scope in Maven?
- What is a transitive dependency?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.