DefaultTask Object Type in Gradle

Gradle tasks are actually objects and a task object has properties and methods just like any other object. By default, each new task receives a type of DefaultTask in Gradle (similar to how all classes are children of the Object class in Java). DefaultTask only contain the functionality required for them to interface with the Gradle project model and do not do any additional actions such as compiling or executing code.

 

Important methods of DefaultTask

dependsOn(task)

Adds task dependency.

All dependencies will be run before the current task.

You can add dependency in many different ways. Most common form is as:

task current {

dependsOn before

}

Or the shortcut form for the same as:

task current (dependsOn: before)

Other alternate forms for using dependsOn are:

dependsOn << before

dependsOn ‘before’

current.dependsOn before

You can also have multiple dependencies as:

dependsOn << before1

dependsOn << before2

or

dependsOn before1, before2

or

current.dependsOn before1, before2

or

task current (dependsOn: [before1, before2])

 

doFirst(closure)

Adds a block of code to the beginning of a task’s action.

You can even use this to add code before an action defined by a build file or a plug-in that you don’t control.

You can invoke the doFirst method directly on the task object, passing a closure to the method.

If you have more than one doFirst method, last one defined will be called first, then second last abd so on (similar to a Stack).

task helloTask << {

  println 'Hello World'

}

helloTask.doFirst {

  println 'Do First 1'

}

helloTask.doFirst {

  println 'Do First 2'

}

When executed as ‘gradle -q helloTask’, you will get the output as:

Do First 2

Do First 1

Hello World

 

You can also call doFirst method from within the configuration block.

Configuration blocks will be executed first, followed by all doFirst actions in reverse order, followed by actual task actions.

Example:

task helloTask << {

  println 'Hello World'

}

helloTask {

  println 'Inside config block 1'

  helloTask.doFirst {

    println 'Do First 1'

  }

  helloTask.doFirst {

    println 'Do First 2'

  }

println 'Inside config block 1 after doFirst call'

}

 

helloTask {

  println 'Inside config block 2'

  helloTask.doFirst {

    println 'Do First 3'

  }

  helloTask.doFirst {

    println 'Do First 4'

  }

}

When executed as ‘gradle –q helloTask’, you will get the output as:

Inside config block 1

Inside config block 1 after doFirst call

Inside config block 2

Do First 4

Do First 3

Do First 2

Do First 1

Hello World

Wrapping inside configuration block is also a good way to group similar doFirst calls.

 

doLast(closure)

doLast is similar to doFist and execute the block of code after the task than before.

If you change all doFirst to doLast in the previous example (including println statements) and execute ‘gradle -q helloTask’, you will get the below output:

Inside config block 1

Inside config block 1 after doLast call

Inside config block 2

Hello World

Do Last 1

Do Last 2

Do Last 3

Do Last 4

All the DoLast calls are executed in order (FIFO) and all DoFirst calls are executed in order LIFO.

Any doFirst or doLast calls done from within a task action (execution phase) are not considered; doFirst or doLast calls should be outside all blocks or within configuration blocks.

 

onlyIf(closure)

We can execute a task conditionally.

task helloTask << {

  println 'Hello World'

}

 

helloTask.onlyIf {

System.properties['sys.prop'] == 'abcd'

}

helloTask is executed only if we have a system property 'sys.prop' with value abcd.

When executed as ‘gradle -q helloTask’, we get a blank output.

When executed as ‘gradle -Dsys.prop=abcd -q helloTask’, we get output as:

Hello World

 

Quiz

Question 1: Predict output

task helloTask << {

  println 'Hello World'

}

 

helloTask {

  println 'Inside config block 1'

 

  helloTask.doLast {

    println 'Do Last 1'

  }

  println 'Inside config block 1 after doLast call'

}

 

helloTask << {

  println 'Inside block 2'

 

  helloTask.doLast {

    println 'Do Last 2'

  }

}

 

Answer 1:

Output differed when using Gradle 1.11 and 2.1 versions.

Common output part for Gradle 1.11 and 2.1 versions:

Inside config block 1

Inside config block 1 after doLast call

Hello World

Do Last 1

Inside block 2

doFirst or doLast calls done from within a task action (execution phase) are not considered; either doFirst or doLast calls should be outside all blocks or within configuration blocks.

If you replace all doLast with doFirst and Last with First, you will get below output:

Inside config block 1

Inside config block 1 after doLast call

Do First 1

Hello World

Inside block 2

The doFIrst is executed before execution (Hello World). And doFirst within the execution block is ignored.

 

While executing using Gradle 2.1, below error was also thrown after above output:

FAILURE: Build failed with an exception.

* Where:
Build file '<path-omitted>\build.gradle' line: 20

* What went wrong:
Execution failed for task ':helloTask'.
> Cannot call Task.doLast(Closure) on task ':helloTask' after task has started execution. Check the configuration of task ':helloTask' as you may have misused '<<' at task declaration.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

Similar exception was thrown while using doFirst also, after printing the statements similar to previous case.

 

References

http://www.gradle.org

Book: Building and Testing with Gradle by Tim Berglund and Matthew McCullough.

 

Software Versions Tested Against

Examples in this note has been tested against Gradle versions 1.11 and 2.1.

Quick Notes Finder Tags

Activities (1) advanced java (1) agile (3) App Servers (6) archived notes (2) Arrays (1) Best Practices (12) Best Practices (Design) (3) Best Practices (Java) (7) Best Practices (Java EE) (1) BigData (3) Chars & Encodings (6) coding problems (2) Collections (15) contests (3) Core Java (All) (55) course plan (2) Database (12) Design patterns (8) dev tools (3) downloads (2) eclipse (9) Essentials (1) examples (14) Exception (1) Exceptions (4) Exercise (1) exercises (6) Getting Started (18) Groovy (2) hadoop (4) hibernate (77) hibernate interview questions (6) History (1) Hot book (5) http monitoring (2) Inheritance (4) intellij (1) java 8 notes (4) Java 9 (1) Java Concepts (7) Java Core (9) java ee exercises (1) java ee interview questions (2) Java Elements (16) Java Environment (1) Java Features (4) java interview points (4) java interview questions (4) javajee initiatives (1) javajee thoughts (3) Java Performance (6) Java Programmer 1 (11) Java Programmer 2 (7) Javascript Frameworks (1) Java SE Professional (1) JPA 1 - Module (6) JPA 1 - Modules (1) JSP (1) Legacy Java (1) linked list (3) maven (1) Multithreading (16) NFR (1) No SQL (1) Object Oriented (9) OCPJP (4) OCPWCD (1) OOAD (3) Operators (4) Overloading (2) Overriding (2) Overviews (1) policies (1) programming (1) Quartz Scheduler (1) Quizzes (17) RabbitMQ (1) references (2) restful web service (3) Searching (1) security (10) Servlets (8) Servlets and JSP (31) Site Usage Guidelines (1) Sorting (1) source code management (1) spring (4) spring boot (3) Spring Examples (1) Spring Features (1) spring jpa (1) Stack (1) Streams & IO (3) Strings (11) SW Developer Tools (2) testing (1) troubleshooting (1) user interface (1) vxml (8) web services (1) Web Technologies (1) Web Technology Books (1) youtube (1)