Gradle Tasks

Introduction

Gradle builds are graphs of tasks—compile, test, jar, and your own steps. Tasks declare inputs and outputs so Gradle can skip work (incremental builds) and cache results. This chapter covers built-in Java tasks, common CLI commands, and simple custom tasks.

Prerequisites

Task Model

Each task has:

  • Actions — code in doFirst / doLast or plugin logic
  • Dependencies — other tasks that must run first
  • Inputs/outputs — files and properties for up-to-date checks
text
compileJava  ──dependsOn──>  processResources
test         ──dependsOn──>  classes
jar          ──dependsOn──>  classes
build        ──dependsOn──>  assemble, check

Unlike Maven’s fixed phases, you can insert tasks anywhere in the graph.

List Tasks

bash
./gradlew tasks
./gradlew tasks --group=build

Shows description, group, and dependencies for discovery.

Common Built-in Tasks (Java Plugin)

TaskPurpose
cleanDelete build/
compileJavaCompile src/main/java
processResourcesCopy src/main/resources
classesCompile + resources
compileTestJavaCompile tests
testRun JUnit
jarPackage main classes
assembleBuild artifacts (jar)
checkRun verifications (tests)
buildassemble + check
bash
./gradlew build
./gradlew test
./gradlew clean build

Skip Tests

bash
./gradlew build -x test

Warning

Skipping tests speeds broken local experiments—not a release strategy. CI should run ./gradlew build with tests enabled.

Debug Failed Builds

bash
./gradlew build --stacktrace
./gradlew build --info
./gradlew build --scan

--stacktrace prints the root cause; --info logs more detail.

Task Dependencies in Scripts

gradle
tasks.named('test') {
    dependsOn 'integrationTest'
}

Ordering without dependency:

gradle
tasks.named('publish') {
    mustRunAfter 'test'
}

mustRunAfter does not force test to run—only orders if both execute.

Register a Custom Task

gradle
tasks.register('hello') {
    group = 'sample'
    description = 'Print a greeting'
    doLast {
        println 'Hello from a custom task'
    }
}
bash
./gradlew hello

Copy Files Example

gradle
tasks.register('copyReadme', Copy) {
    group = 'distribution'
    from('README.md')
    into("$buildDir/dist")
}
bash
./gradlew copyReadme

Built-in task types (Copy, Delete, Exec) encapsulate common work.

doFirst and doLast

gradle
tasks.named('test') {
    doFirst {
        println 'Starting tests...'
    }
    doLast {
        println 'Tests finished.'
    }
}

Compare with Maven Phases

MavenGradle (typical)
mvn compile./gradlew compileJava
mvn test./gradlew test
mvn package./gradlew build or jar
mvn clean./gradlew clean

Gradle has more granular task names; build is the usual “do everything” entry.

Mini Example: Zip Dist Folder

gradle
tasks.register('distZip', Zip) {
    group = 'distribution'
    dependsOn 'jar'
    archiveFileName = 'app-dist.zip'
    destinationDirectory = layout.buildDirectory.dir('dist')
    from jar.outputs.files
    from('README.md')
}
bash
./gradlew distZip

FAQ

Task vs plugin?

Plugins register many tasks and wire them together. You call tasks; plugins provide the graph.

Why did compileJava run but not test?

You invoked a specific task—dependencies still run; unrelated branches may skip.

Parallel execution?

Gradle runs independent tasks in parallel when org.gradle.parallel=true.

What comes next?

Gradle plugins.