Gradle Basics

Modern Build Automation for Java

← Back to Index

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