Skip to main content

Gradle Fundamentals

Gradle is a modern, flexible build automation tool that uses a Groovy or Kotlin-based Domain Specific Language (DSL). It improves upon Maven and Ant by combining their best features with powerful scripting capabilities.

What is Gradle?

Gradle is an open-source build automation tool that automates the compilation, testing, packaging, and deployment of software. It evolved from Ant and Maven, addressing their limitations while providing superior performance and flexibility.

Key characteristics:

  • Convention over Configuration — Sensible defaults reduce boilerplate
  • Incremental Builds — Only rebuilds what changed
  • Powerful DSL — Groovy or Kotlin-based, not XML
  • Plugin Ecosystem — Extensible with custom plugins
  • Dependency Management — Advanced resolution and caching
  • Multi-Project Builds — Efficient builds for complex projects

History and Evolution

Ant → Maven → Gradle

Ant (2000)

  • Procedural XML syntax
  • Full control but verbose
  • Limited dependency management

Maven (2004)

  • Declarative XML
  • Convention-based structure
  • Built-in dependency management
  • Struggled with complex customizations

Gradle (2012)

  • Groovy/Kotlin DSL
  • Combines best of both worlds
  • Incremental compilation
  • Superior performance

Core Concepts

Build Script Structure

// build.gradle

// 1. Apply plugins
plugins {
id 'java'
id 'application'
}

// 2. Configure source and target versions
java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

// 3. Define repositories
repositories {
mavenCentral()
google()
}

// 4. Declare dependencies
dependencies {
implementation 'com.google.guava:guava:31.0-jre'
testImplementation 'junit:junit:4.13.2'
}

// 5. Configure application
application {
mainClass = 'com.example.App'
}

// 6. Define custom tasks
tasks.register('hello') {
doLast {
println 'Hello, World!'
}
}

Project Structure

my-project/
├── gradle/ # Gradle wrapper files
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── src/
│ ├── main/
│ │ ├── java/
│ │ └── resources/
│ └── test/
│ ├── java/
│ └── resources/
├── build.gradle # Build configuration
├── gradle.properties # Gradle properties
├── settings.gradle # Multi-project configuration
├── gradlew # Gradle wrapper script
├── gradlew.bat # Gradle wrapper (Windows)
└── pom.xml # Optional: Legacy Maven config

Groovy vs Kotlin DSL

Groovy DSL (Traditional)

// build.gradle
plugins {
id 'java'
}

repositories {
mavenCentral()
}

dependencies {
implementation 'junit:junit:4.13.2'
}

tasks {
build {
doLast {
println "Build complete!"
}
}
}

Kotlin DSL (Modern)

// build.gradle.kts
plugins {
id("java")
}

repositories {
mavenCentral()
}

dependencies {
implementation("junit:junit:4.13.2")
}

tasks {
build {
doLast {
println("Build complete!")
}
}
}

Advantages of Kotlin DSL:

  • Type-safe
  • IDE autocomplete support
  • Compile-time error checking
  • Better for large builds

Tasks

Defining Tasks

// Simple task
task hello {
doLast {
println 'Hello, World!'
}
}

// Task with inputs and outputs
task processData {
inputs.file 'data/input.txt'
outputs.file 'data/output.txt'
doLast {
// Process file
}
}

// Task with description
task deploy {
description = 'Deploy application'
group = 'deployment'
doLast {
println 'Deploying...'
}
}

// Task with dependencies
task compile
task test {
dependsOn compile
}

// Task ordering
task buildApp {
mustRunAfter test
}

Running Tasks

# List available tasks
gradle tasks

# Run specific task
gradle hello
gradle build

# Run multiple tasks
gradle clean build test

# Run with options
gradle build --debug
gradle test -x integrationTest # Exclude integration tests

# Parallel builds
gradle build -x test --parallel

# Show detailed output
gradle build --info

Plugins

Using Plugins

plugins {
id 'java' // Core Java plugin
id 'org.springframework.boot' version '2.6.0' // Third-party plugin
id 'com.example.custom' // Custom plugin
}

Common Plugins

plugins {
id 'java' // Java compilation, testing
id 'application' // Create executable JARs
id 'maven-publish' // Publish to Maven repos
id 'java-library' // Java library (exports API)
}

Built-in Java Plugin Tasks

The java plugin automatically provides:

TaskPurpose
compileJavaCompile source code
processResourcesProcess resource files
classesCompile and process resources
jarCreate JAR archive
testRun unit tests
buildFull build (depends on all above)
cleanRemove build artifacts

Dependency Management

Repository Configuration

repositories {
// Central Maven repository
mavenCentral()

// Google's Maven repository
google()

// JCenter (deprecated, but some projects still use)
jcenter()

// Custom repository
maven {
url = uri('https://repo.company.com/releases')
credentials {
username = 'user'
password = 'pass'
}
}

// Ivy repository
ivy {
url = uri('https://ivy.company.com')
}
}

Declaring Dependencies

dependencies {
// Implementation dependency (compiled and on runtime classpath)
implementation 'com.google.guava:guava:31.0-jre'

// API dependency (exposed to consumers)
api 'org.apache.commons:commons-lang3:3.12.0'

// Test implementation
testImplementation 'junit:junit:4.13.2'

// Annotation processor
annotationProcessor 'org.projectlombok:lombok:1.18.22'

// Runtime only
runtimeOnly 'mysql:mysql-connector-java:8.0.26'

// Multiple dependencies
implementation(
'com.google.guava:guava:31.0-jre',
'org.apache.commons:commons-lang3:3.12.0'
)

// With version constraint
implementation 'org.slf4j:slf4j-api:1.7.+'
}

Dependency Resolution

// Exclude transitive dependency
dependencies {
implementation('org.springframework.boot:spring-boot-starter') {
exclude module: 'spring-boot-starter-logging'
}
}

// Force version
configurations.all {
resolutionStrategy {
force 'org.slf4j:slf4j-api:1.7.36'
}
}

Multi-Project Builds

Settings File

// settings.gradle
rootProject.name = 'my-app'

include(
'shared',
'api',
'web',
'cli'
)

// Nested modules
include(':services:auth')
include(':services:payment')

Project Structure

my-app/
├── settings.gradle
├── build.gradle # Root build configuration
├── shared/
│ └── build.gradle
├── api/
│ └── build.gradle
├── web/
│ └── build.gradle
└── cli/
└── build.gradle

Root Build Configuration

// build.gradle - Apply to all projects
allprojects {
group = 'com.example'
version = '1.0.0'
}

// Apply only to subprojects
subprojects {
repositories {
mavenCentral()
}

dependencies {
testImplementation 'junit:junit:4.13.2'
}
}

// Project-specific configuration
project(':api') {
dependencies {
implementation project(':shared')
}
}

Build Properties

gradle.properties

# JVM arguments
org.gradle.jvmargs=-Xmx2g

# Parallel builds
org.gradle.parallel=true

# Gradle daemon
org.gradle.daemon=true

# Build cache
org.gradle.build.cache=true

# Logging level
org.gradle.logging.level=lifecycle

# Custom properties
app.version=1.0.0
java.version=11

System Properties

# Via command line
gradle build -Dorg.gradle.jvmargs=-Xmx4g

# Via environment variable
export GRADLE_OPTS=-Xmx4g
gradle build

# Via properties file
echo "org.gradle.jvmargs=-Xmx4g" >> gradle.properties

Java Configuration

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

// Or using compiler options
tasks.compileJava {
options.release = 11
}

Testing

// Configure test task
test {
useJUnit() // Use JUnit 4

testLogging {
events "passed", "skipped", "failed"
showStandardStreams = true
}
}

// Or JUnit 5
test {
useJUnitPlatform()
}

// Skip tests during build
gradle build -x test

// Run specific test
gradle test --tests *TestClass

Gradle Wrapper

The Gradle Wrapper allows projects to be built without Gradle installation:

# Create wrapper
gradle wrapper

# Or specify version
gradle wrapper --gradle-version 7.0

# Run with wrapper (Unix)
./gradlew build

# Run with wrapper (Windows)
gradlew.bat build

Performance Optimization

// Enable build cache
org.gradle.build.cache=true

// Parallel builds
org.gradle.parallel=true

// Daemon (background process)
org.gradle.daemon=true

// Incremental compilation
compileJava {
options.incremental = true
}

Custom Plugins

// build.gradle - Custom task
class GreetingTask extends DefaultTask {
@Input
String greeting = 'Hello'

@TaskAction
void greet() {
println "$greeting from $name"
}
}

tasks.register('myGreeting', GreetingTask) {
greeting = 'Hi'
}

Exercises

Exercise 1: Basic Java Project

  1. Create a new Gradle Java project
  2. Define a simple main class
  3. Configure dependencies (JUnit for testing)
  4. Build and run the JAR

Exercise 2: Multi-Project Build

  1. Create a multi-project structure
  2. Configure dependency between projects
  3. Build entire project structure
  4. Verify builds complete successfully

Exercise 3: Custom Tasks

  1. Define a custom Gradle task
  2. Configure task dependencies
  3. Add task descriptions and groups
  4. Execute and verify output

Exercise 4: Dependency Management

  1. Add multiple dependencies
  2. Exclude transitive dependencies
  3. Force specific versions
  4. Build and verify resolution

Exercise 5: Plugin Development

  1. Create a simple Gradle plugin
  2. Apply plugin to build
  3. Configure plugin settings
  4. Verify plugin functionality

Common Build Patterns

Simple Application

plugins {
id 'java'
id 'application'
}

java {
sourceCompatibility = JavaVersion.VERSION_11
}

repositories {
mavenCentral()
}

dependencies {
implementation 'com.google.guava:guava:31.0-jre'
testImplementation 'junit:junit:4.13.2'
}

application {
mainClass = 'com.example.Main'
}

Library Project

plugins {
id 'java-library'
id 'maven-publish'
}

java {
sourceCompatibility = JavaVersion.VERSION_11
}

repositories {
mavenCentral()
}

dependencies {
api 'com.google.guava:guava:31.0-jre'
}

publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
}

Summary

Gradle is a powerful, modern build tool that:

  • Provides flexible Groovy/Kotlin DSL
  • Handles complex multi-project builds efficiently
  • Manages dependencies with precision
  • Integrates deeply with the Java ecosystem
  • Offers excellent performance and caching

Master Gradle to build scalable, maintainable Java projects.