Java Academy Logo

Dependency Management in Gradle

Let's start with a simple Gradle script for Java projects:

build.gradle
plugins {
    id 'java'
}
repositories {
    mavenCentral()
}
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter:2.3.4.RELEASE'
    testImplementation 'org.springframework.boot:spring-boot-starter-test:2.3.4.RELEASE'
}

This Gradle script sets up a basic Java project.

  • The plugins block applies the Java plugin, telling Gradle this is a Java project.
  • The repositories block specifies that dependencies should be downloaded from Maven Central.
  • The dependencies block adds Spring Boot:
    • spring-boot-starter (version 2.3.4.RELEASE) for the main application code
    • spring-boot-starter-test (same version) for testing

Dependency Configurations

There are different configurations in which we can declare dependencies. In this regard, we can choose to be more or less precise, as we'll see later on.

How to Declare Dependencies

A dependency is defined using four parts:

  • group – who makes it (organization or project)
  • name – the dependency's name
  • version – which version to use
  • classifier – optional, used to tell similar dependencies apart

Gradle lets you declare dependencies in different ways. The simplest is the short (string) format, like this:

build.gradle
implementation 'org.springframework.boot:spring-boot-starter:2.3.4.RELEASE'

Types of Dependency Configurations

Gradle offers different configuration types to control when and how dependencies are used:

api

Exposed to other projects that depend on this one

implementation

Used internally for main code only

compileOnly

Needed only during compilation, not at runtime

compileOnlyApi

Needed at compile time and visible to consumers

runtimeOnly

Needed only when the app runs

testCompileOnly

Needed only to compile tests

testRuntimeOnly

Needed only when running tests

Types of Dependencies in Gradle

1. Module Dependencies

The most common way to add dependencies is from a repository (like Maven Central). Gradle downloads them using the repositories block.

build.gradle
repositories {
    mavenCentral()
}
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter:2.3.4.RELEASE'
}

2. File Dependencies

If dependencies are stored locally, you can include them by specifying their file paths.

Specific JAR files:

build.gradle
dependencies {
    runtimeOnly files('libs/lib1.jar', 'libs/lib2.jar')
}

All JARs in a folder:

build.gradle
dependencies {
    runtimeOnly fileTree('libs') { include '*.jar' }
}

3. Project Dependencies

One project can depend on another within the same build.

build.gradle
dependencies {
    implementation project(':shared')
}

4. Gradle Dependencies

When building Gradle plugins or tasks, you can depend on Gradle's own API.

build.gradle
dependencies {
    implementation gradleApi()
}

buildscript

The dependencies block is for your application code.

The buildscript block is for Gradle itself.

It lets you add dependencies that Gradle needs to run the build, such as plugins and custom tasks. Without it, you can only use Gradle's built-in features.

Example: adding the Spring Boot plugin from Maven Central:

build.gradle
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.3.4.RELEASE'
    }
}
apply plugin: 'org.springframework.boot'

This tells Gradle to download and use the Spring Boot plugin for the build.