What is Gradle?
Gradle is a flexible, fast build automation tool that uses a Groovy or Kotlin DSL instead of XML. It combines the best of Maven and Ant with powerful dependency management and build customization.
Gradle vs Maven
- Configuration - Groovy/Kotlin DSL vs XML
- Performance - Incremental builds, build cache
- Flexibility - More customizable build logic
- Compatibility - Can use Maven repositories
Project Structure
# Typical Gradle project structure
my-project/
├── build.gradle.kts # Build script (Kotlin DSL)
├── settings.gradle.kts # Settings script
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew # Unix wrapper script
├── gradlew.bat # Windows wrapper script
└── src/
├── main/
│ ├── java/
│ └── resources/
└── test/
├── java/
└── resources/
Build Script (Kotlin DSL)
Basic build.gradle.kts
// Plugins
plugins {
java
application
}
// Project metadata
group = "com.example"
version = "1.0.0"
// Java version
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
// Repositories
repositories {
mavenCentral()
}
// Dependencies
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:3.2.0")
implementation("com.fasterxml.jackson.core:jackson-databind:2.15.3")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
// Application main class
application {
mainClass.set("com.example.Application")
}
// Test configuration
tasks.test {
useJUnitPlatform()
}
Groovy DSL (build.gradle)
// Equivalent in Groovy DSL
plugins {
id 'java'
id 'application'
}
group = 'com.example'
version = '1.0.0'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:3.2.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}
application {
mainClass = 'com.example.Application'
}
test {
useJUnitPlatform()
}
Common Tasks
# Build commands
./gradlew build # Compile, test, and package
./gradlew clean # Delete build/ directory
./gradlew clean build # Clean then build
# Compile
./gradlew compileJava # Compile main sources
./gradlew compileTestJava # Compile test sources
./gradlew classes # Compile and process resources
# Testing
./gradlew test # Run tests
./gradlew test --tests "UserTest" # Run specific test class
./gradlew test --tests "*Service*" # Pattern matching
# Run application
./gradlew run # Run application (needs application plugin)
# Dependencies
./gradlew dependencies # Show dependency tree
./gradlew dependencyInsight --dependency jackson-core
# Info
./gradlew tasks # List available tasks
./gradlew properties # List project properties
Dependency Configurations
dependencies {
// Compile-time and runtime
implementation("com.google.guava:guava:32.1.3-jre")
// Compile-time only (not in runtime classpath)
compileOnly("org.projectlombok:lombok:1.18.30")
annotationProcessor("org.projectlombok:lombok:1.18.30")
// Runtime only (not needed for compilation)
runtimeOnly("org.postgresql:postgresql:42.6.0")
// Test dependencies
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
// API vs Implementation (for library projects)
api("com.example:public-api:1.0") // Exposed to consumers
implementation("com.example:internal:1.0") // Hidden from consumers
}
Configuration Guide
- implementation - Standard dependency (recommended)
- api - Exposed to consumers (library projects)
- compileOnly - Compile-time only (Lombok, etc.)
- runtimeOnly - Runtime only (JDBC drivers)
- testImplementation - Test compile and runtime
Multi-Project Builds
settings.gradle.kts
// Root settings file
rootProject.name = "my-project"
include("api")
include("service")
include("web")
Root build.gradle.kts
// Configure all subprojects
subprojects {
apply(plugin = "java")
repositories {
mavenCentral()
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
}
}
// Configure specific project
project(":service") {
dependencies {
implementation(project(":api")) // Project dependency
}
}
Custom Tasks
// Simple task
tasks.register("hello") {
doLast {
println("Hello, Gradle!")
}
}
// Task with dependencies
tasks.register("buildAll") {
dependsOn("clean", "build")
doLast {
println("Build completed!")
}
}
// Typed task (Copy)
tasks.register<Copy>("copyDocs") {
from("docs")
into("build/docs")
include("**/*.md")
}
// Task configuration
tasks.named<Jar>("jar") {
manifest {
attributes(
"Main-Class" to "com.example.Main",
"Implementation-Version" to project.version
)
}
}
Spring Boot with Gradle
plugins {
java
id("org.springframework.boot") version "3.2.0"
id("io.spring.dependency-management") version "1.1.4"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_17
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.test {
useJUnitPlatform()
}
// Spring Boot tasks:
// ./gradlew bootRun - Run application
// ./gradlew bootJar - Create executable JAR
// ./gradlew bootBuildImage - Create Docker image
Gradle Wrapper
# Generate or update wrapper
gradle wrapper --gradle-version 8.5
# Always use wrapper in projects
./gradlew build # Unix/Mac
gradlew.bat build # Windows
# gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Always Use the Wrapper
Commit the wrapper files to version control. This ensures all developers and CI use the same Gradle version.
Performance Features
# gradle.properties - Performance settings
org.gradle.parallel=true # Parallel project execution
org.gradle.caching=true # Enable build cache
org.gradle.daemon=true # Use Gradle daemon (default)
org.gradle.jvmargs=-Xmx2g # Increase memory
# Configuration cache (experimental but fast)
org.gradle.configuration-cache=true
# Command line options
./gradlew build --parallel
./gradlew build --build-cache
./gradlew build --no-daemon # Disable daemon for this run
Maven vs Gradle Comparison
| Feature | Maven | Gradle |
|---|---|---|
| Configuration | pom.xml (XML) | build.gradle.kts (Kotlin) |
| Build speed | Slower | Faster (incremental + cache) |
| Learning curve | Easier | Steeper |
| Customization | Limited | Highly flexible |
| IDE support | Excellent | Excellent |