Using Gradle DefaultTask Classes

Gradle provides the DefaultTask class, and many task classes are implemented by extending it. This page explains how to create tasks using such classes.

Classes That Extend DefaultTask

Gradle includes many standard tasks, and many of them are classes that extend DefaultTask. You can also create your own task class by extending DefaultTask.

A class that extends DefaultTask is defined in the following form.

class ClassName extends DefaultTask {
    // fields

    void method(arguments) {
        // processing
    }

    @TaskAction
    void method() {
        // processing
    }
}

The class extends DefaultTask and provides methods that perform task processing. The method to run as the task action is marked with @TaskAction. When the task is executed, that method is called.

Values used by the task can be stored in fields. For values accessed from outside, it is usually cleaner to keep fields private and provide methods for setting them.

The following is a simple example.

class Calc extends DefaultTask {
    private int num
    private String op
 
    void num(p1){
        num = p1
    }
 
    void op(p1){
        op = p1
    }
 
    @TaskAction 
    void calc() {
        switch(op) {
        case 'total':
            int total = 0
            for(def i in 1..num) {
                total += i
            }
            println("total: ${total}")
        break
 
        case 'count':
            for(def i in 1..num) {
                println("NO, ${i}")
            }
        break
 
        default:
            println('not found operator...')
        }
    }
}

The Calc class provides a task action named calc. It calculates a total or prints a count depending on the values of num and op.

Tasks using the Calc class

A task that uses a class extending DefaultTask is written as follows.

task taskName(type : ClassName) {
    // processing to execute
}

Specify the class to use with the type argument. Inside the task, set values used by the class fields. Then the task action runs with those configured values.

task total(type:Calc) {
    group 'devkuma'
    description 'Task for calculating total.'
    num 100
    op 'total'
}
 
task count(type:Calc) {
    group 'devkuma'
    description 'Task for count number.'
    num 10
    op 'count'
}

These examples define total and count tasks whose type is Calc. Running gradle total calculates the sum up to 100.

$ gradle total

> Task :total
total: 5050


BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

Running gradle count prints numbers from 1 to 10.

$ gradle count

> Task :count
NO, 1
NO, 2
NO, 3
NO, 4
NO, 5
NO, 6
NO, 7
NO, 8
NO, 9
NO, 10


BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

The task is defined with (type:Calc), so it executes the task action provided by the Calc class. The task block calls methods such as group, description, num, and op. group and description are provided by DefaultTask, while num and op are methods defined in Calc.

Using the JavaExec Class

After understanding the basics of custom tasks that extend DefaultTask, it is useful to look at standard task classes provided by Gradle.

JavaExec class

JavaExec implements a task for running a Java program. It provides several methods required for execution.

main "ClassName"

Specifies the class to execute.

classpath "text"

Specifies the classpath used at runtime. For the default classpath, use sourceSets.main.runtimeClasspath.

args "Iterator"
args "value1, value2, ..."

Specifies arguments passed to the program. They can be prepared as an iterator or listed individually.

jvmArgs "Iterator"
jvmArgs "value1, value2, ..."

Specifies arguments passed to the Java Virtual Machine.

workingDir "text"

Specifies the working directory. Use a path relative to the project directory.

The following example uses JavaExec.

task appRun(type: JavaExec) {
    group 'devkuma'
    description 'exec App class.'
    main 'App'
    classpath sourceSets.main.runtimeClasspath
     
    doFirst {
        println()
        println('---------- Start ----------')
        println()
    }
    doLast {
        println()
        println('----------- end -----------')
        println()
    }
}

This creates an appRun task that executes the App class. Running gradle appRun prints the following.

$ gradle appRun

> Task :appRun

---------- Start ----------

Hello world.

----------- end -----------

Gradle output can make it hard to see the actual result, so doFirst and doLast print delimiters around the execution output. The required JavaExec settings are:

main 'App'
classpath sourceSets.main.runtimeClasspath

These two settings are required because they do not have useful defaults.

Running Commands with Exec

Sometimes you need to run a program other than the Java program being developed. In that case, use the Exec class.

Exec runs commands from the command line and provides methods for configuring command execution.

commandLine "command", "argument"...

Specifies the command to execute. The first argument is the command, and the rest are options or command arguments.

workingDir "text"

Specifies the working directory.

args "Iterator"
args "value1, value2, ..."

Specifies arguments passed to the command.

Running on Windows

The following example assumes Windows. Create a file named java.bat in the project directory.

java.exe -version

Then define this task.

task javaVer(type:Exec) {
    group 'devkuma'
    description 'print java version.'
    workingDir '.'
    commandLine 'cmd'
    args '/c', 'java.bat'
    doFirst {
        println()
        println('***** Java Version *****')
    }
}

Run gradle javaVer. The output will vary depending on the installed JDK, but it is similar to the following.

> Task :javaVer

***** Java Version *****

C:\dev\GradleApp>java.exe -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

The settings run cmd /c java.bat, which executes java.exe -version.

Running on macOS and Linux

For macOS or Linux, define a task like this.

task javaVer(type:Exec) {
    group 'devkuma'
    description 'print java version.'
    workingDir '.'
    commandLine './javaver'
    doFirst {
        println()
        println('***** Java Version *****')
    }
}

Create a javaver file with the following content and grant execute permission with chmod.

java -version

The output is similar to the Windows example.

Copying Files with Copy

Gradle also provides useful file-related task classes.

Copy class

The Copy class copies files. It provides the following methods.

from "source path"

Specifies the source file or directory path.

into "destination path"

Specifies the destination path.

include "pattern", ...

Specifies files to include using Ant-style patterns.

exclude "pattern", ...

Specifies files to exclude using Ant-style patterns.

Example:

task copyJava(type: Copy) {
    group 'devkuma'
    description 'backup java files.'
    from 'src/main/java'
    into '../java_backup'
 }

This copies the java directory under main to java_backup outside the project directory. Run it with gradle copyJava.

Delete class

The Delete class deletes files and directories.

delete "file", ...

Specify the files to delete by path.