Alexander KLimov
Alexander KLimov

Reputation: 61

Gradle: any difference between task configuration approaches

Is there any difference between two following pieces of code?
May be there is some difference about eager initialization of a task?

tasks.bootJar {
    archiveFileName = "some-name"
}

and

bootJar {
    archiveFileName = "some-code"
}

Upvotes: 2

Views: 429

Answers (1)

Cisco
Cisco

Reputation: 23042

They are the effectively the same just different syntax. Both cause the task to be realized or eager initialized. You can confirm this by simply running with debug output: ./gradlew -d

You will see the following line logged:

[DEBUG] [org.gradle.internal.operations.DefaultBuildOperationRunner] Build operation 'Realize task :bootJar' started

For the Groovy DSL, the Gradle team takes advantage of the metaprogramming offered by the Groovy language to dynamically make tasks, extensions, properties, and more "magically" available.

So for this example:

tasks.bootJar {
    archiveFileName = "some-name"
}

tasks is of type TaskContainer. If you were to examine all available methods and properties for TaskContainer, you will see that bootJar is not one of them. So Gradle hooks into the Groovy metaprogramming to search for something named bootJar. Since it's on the TaskContainer type, it can be assumed that bootJar is a task.

So if you were to desugar the DSL, the first example is effectively:

tasks.getByName("bootJar") {

}

Now for the second example:

bootJar {
    archiveFileName = "some-code"
}

The default scope or this in a Gradle build file is Project. Again, just like before, if you were to examine all available methods and properties, you will not see bootJar as one of them.

Groovy's 'magic' is at play here, but this time around, Gradle will search (my understanding) practically everywhere because there is a lot more available on a Project.

project.extensions.named("bootJar") // exists?
project.hasProperty("bootJar") // exists?
project.tasks.getByName("bootJar") // found it!

To summarize, no there is no difference between the two since both cause the bootJar task to be realized. Use task configuration avoidance wherever possible to make your Gradle builds more efficient:

import org.springframework.boot.gradle.tasks.bundling.BootJar

tasks.named("bootJar", BootJar) {
    
}

Upvotes: 4

Related Questions