Dependency Management in Gradle
Introduction
Gradle resolves libraries from repositories into a local cache and wires them onto compile and runtime classpaths. You declare coordinates in dependencies { } using configurations such as implementation and testImplementation. This chapter adds Gson, compares configurations to Maven scopes, and shows how to inspect trees and fix conflicts.
Prerequisites
- Build script basics
- A project with
javaplugin andmavenCentral()repository
Add Gson and Parse JSON
Find coordinates on Maven Central — Gson example:
| Part | Value |
|---|---|
| group | com.google.code.gson |
| artifact | gson |
| version | 2.11.0 |
build.gradle:
dependencies {
implementation 'com.google.code.gson:gson:2.11.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
}Sync or build:
./gradlew buildsrc/main/java/com/example/JsonDemo.java:
Run with application plugin pointing at JsonDemo, or temporarily set mainClass in build.gradle.
Configurations vs Maven Scopes
| Gradle configuration | Typical use | Maven scope (rough) |
|---|---|---|
implementation | App/runtime deps; hide from consumers | compile (modern default) |
api | Library API exposed to dependents | compile + exported |
compileOnly | Needed to compile, not runtime | provided |
runtimeOnly | Runtime only, not compile | runtime |
testImplementation | Unit tests | test |
testRuntimeOnly | Test runtime only | test |
dependencies {
implementation 'com.google.code.gson:gson:2.11.0'
compileOnly 'org.projectlombok:lombok:1.18.34'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.2'
}Tip
Libraries vs Apps
Application projects mostly use implementation. Java library modules use api when types from a dependency appear in public method signatures.
Version Catalog (libs.versions.toml)
Gradle 7+ supports a catalog under gradle/libs.versions.toml:
[versions]
gson = "2.11.0"
junit = "5.10.2"
[libraries]
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
junit-jupiter = { group = "org.junit.jupiter", name = "junit-jupiter", version.ref = "junit" }build.gradle:
dependencies {
implementation libs.gson
testImplementation libs.junit.jupiter
}One file to bump versions across modules—common in Spring Boot 3+ templates.
BOM / Platform Alignment
Import a BOM to align versions (Spring, Jackson, etc.):
dependencies {
implementation platform('org.springframework.boot:spring-boot-dependencies:3.4.0')
implementation 'org.springframework.boot:spring-boot-starter-web'
}Gradle respects BOM constraints when resolving versions.
Inspect the Dependency Tree
# Full runtime classpath tree
./gradlew dependencies --configuration runtimeClasspath
# Compile classpath
./gradlew dependencies --configuration compileClasspathFind why a library appeared:
./gradlew dependencyInsight --dependency gson --configuration compileClasspathExclude Transitive Dependencies
dependencies {
implementation('some.group:some-lib:1.0') {
exclude group: 'commons-logging', module: 'commons-logging'
}
}Use when a transitive JAR causes conflicts or duplicate APIs.
Force a Version (Use Sparingly)
configurations.all {
resolutionStrategy.force 'com.google.code.gson:gson:2.11.0'
}Prefer BOMs or fixing the dependency that pulls the wrong version.
Reuse Maven Local Cache
If you already use Maven:
repositories {
mavenLocal()
mavenCentral()
}Or global ~/.gradle/init.gradle as in IntelliJ chapter.
FAQ
Where are JARs stored?
~/.gradle/caches/modules-2/files-2.1/ (not the same path as ~/.m2 unless you use mavenLocal()).
implementation vs api?
implementation hides transitive deps from your library’s consumers; api exposes them.
Reload after editing build.gradle?
Run ./gradlew build or Reload Gradle in IDEA.