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/doLastor plugin logic - Dependencies — other tasks that must run first
- Inputs/outputs — files and properties for up-to-date checks
compileJava ──dependsOn──> processResources
test ──dependsOn──> classes
jar ──dependsOn──> classes
build ──dependsOn──> assemble, checkUnlike Maven’s fixed phases, you can insert tasks anywhere in the graph.
List Tasks
./gradlew tasks
./gradlew tasks --group=buildShows description, group, and dependencies for discovery.
Common Built-in Tasks (Java Plugin)
| Task | Purpose |
|---|---|
clean | Delete build/ |
compileJava | Compile src/main/java |
processResources | Copy src/main/resources |
classes | Compile + resources |
compileTestJava | Compile tests |
test | Run JUnit |
jar | Package main classes |
assemble | Build artifacts (jar) |
check | Run verifications (tests) |
build | assemble + check |
./gradlew build
./gradlew test
./gradlew clean buildSkip Tests
./gradlew build -x testWarning
Skipping tests speeds broken local experiments—not a release strategy. CI should run ./gradlew build with tests enabled.
Debug Failed Builds
./gradlew build --stacktrace
./gradlew build --info
./gradlew build --scan--stacktrace prints the root cause; --info logs more detail.
Task Dependencies in Scripts
tasks.named('test') {
dependsOn 'integrationTest'
}Ordering without dependency:
tasks.named('publish') {
mustRunAfter 'test'
}mustRunAfter does not force test to run—only orders if both execute.
Register a Custom Task
tasks.register('hello') {
group = 'sample'
description = 'Print a greeting'
doLast {
println 'Hello from a custom task'
}
}./gradlew helloCopy Files Example
tasks.register('copyReadme', Copy) {
group = 'distribution'
from('README.md')
into("$buildDir/dist")
}./gradlew copyReadmeBuilt-in task types (Copy, Delete, Exec) encapsulate common work.
doFirst and doLast
tasks.named('test') {
doFirst {
println 'Starting tests...'
}
doLast {
println 'Tests finished.'
}
}Compare with Maven Phases
| Maven | Gradle (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
tasks.register('distZip', Zip) {
group = 'distribution'
dependsOn 'jar'
archiveFileName = 'app-dist.zip'
destinationDirectory = layout.buildDirectory.dir('dist')
from jar.outputs.files
from('README.md')
}./gradlew distZipFAQ
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.