Task Properties

Gradle allows you to define task-specific properties that can be configured dynamically. These properties can be set and modified during the Configuration phase and accessed during the Execution phase.

Example of Task Property:

tasks.register("myTask") {
    // Define a custom task property
    val greeting = project.objects.property(String::class.java)

    // Configure the property during the Configuration phase
    greeting.set("Hello, Gradle!")

    doLast {
        // Access and use the property during the Execution phase
        println(greeting.get())
    }
}
Glass thought Sandbox Snapshot

Command to reproduce:

gt.sandbox.checkout.commit 4beb72b \
&& cd "${GT_SANDBOX_REPO}" \
&& cmd.run.announce "./gradlew myTask"

Recorded output of command:


> Task :lib:myTask
Hello, Gradle!

BUILD SUCCESSFUL in 359ms
1 actionable task: 1 executed

In this example:

  • Task property greeting is defined and configured during the Configuration phase (greeting.set()).
  • The property value is accessed and used during the Execution phase (greeting.get()).

Why use task properties and not variables

Why use task properties and not variables

The use of task properties in Gradle, like project.objects.property(String::class.java), provides important advantages over using regular variables within a task block. Here are the key reasons to use task properties instead of simple variables:

1. Gradle’s Incremental Build Support:

  • Task properties allow Gradle to track inputs and outputs, enabling incremental builds. This means that if the property value hasn't changed, Gradle can avoid re-executing the task, improving build performance.
  • Regular variables like someVariable are not tracked by Gradle, so changes to these won't trigger task re-execution or up-to-date checks.

2. Deferred Configuration:

  • Task properties are part of Gradle’s configuration system and can be configured after the task is defined (even from the command line or other tasks). This makes them more flexible, allowing dynamic behavior depending on the project state.
  • Regular variables are evaluated immediately when the task is configured, and their values are fixed during the configuration phase.

3. Lazy Evaluation:

  • With task properties, you can benefit from lazy evaluation, meaning the property values are only evaluated when accessed in the execution phase. This can help with more complex tasks where you want values to be set dynamically based on other conditions in the build.
  • In contrast, regular variables are eagerly evaluated when the task is configured.

4. Task Serialization:

  • When you define task properties, Gradle can serialize these properties, which is essential when running builds in parallel or in distributed build environments (like using Gradle’s build cache).
  • Regular variables aren’t part of Gradle’s internal task model, so they can’t be tracked, serialized, or cached.

Example Comparison:

Using a Task Property:

tasks.register("myTask") {
    // Define a custom task property
    val greeting = project.objects.property(String::class.java)

    // Configure the property during the Configuration phase
    greeting.set("Hello, Gradle!")

    doLast {
        println(greeting.get())
    }
}
  • Advantages: greeting is tracked by Gradle, can be lazily configured, and can enable incremental build support.

Using a Regular Variable:

tasks.register("myTask") {
    val greeting = "Hello, Gradle!"

    doLast {
        println(greeting)
    }
}
  • Disadvantages: greeting is not tracked by Gradle, so if you change its value or input/output files, Gradle won't know and can't optimize the build. It's also evaluated immediately during configuration.

5. External Configuration:

  • Task properties can be set or overridden via external configurations like the command line or other build scripts, adding to their flexibility.
  • Regular variables are static and cannot be reconfigured dynamically from outside the task definition.

When to Use Task Properties:

  • When tasks need incremental build support, such as for tasks that depend on external input or outputs.
  • When the task properties need to be configured dynamically, for example, based on user input, environment variables, or project states.
  • For tasks running in parallel or in distributed environments, where Gradle needs to serialize and track task state.

Conclusion:

While you can use regular variables for simple cases, task properties offer significant advantages in terms of incremental builds, lazy evaluation, external configuration, and task state tracking, making them crucial for complex, efficient Gradle builds.


Children
  1. Why Not Just Use Variables

Backlinks