Learn the basics of Gradle’s incremental builds.

In this section you will:

  • Update Gradle Properties

  • Understand incremental builds

Step 0. Before you Begin

  1. You initialized your Java app in part 1.

  2. You ran several tasks in part 2.

  3. You learned about dependency management in part 3.

  4. You applied a plugin to your app in part 4.

Step 1. Understanding Incremental Builds

It’s important to know that Gradle optimizes your build in a variety of ways. One such optimization is called incremental builds.

An incremental build is a build that avoids running tasks whose inputs did not change (and therefore the same outputs would be produced) since the previous build, making the execution of such tasks unnecessary.

To re-iterate, tasks can define their own inputs and outputs. At build time, Gradle will determine whether they have changed or not. If the inputs have changed, Gradle will execute the task. Otherwise, it won’t.

Step 2. Updating Gradle Properties

In the top-level folder of your app (tutorial), create a gradle.properties file.

$ touch gradle.properties

Add org.gradle.console=verbose so the contents of the file look like this:

org.gradle.console=verbose

Step 3. Analyzing Incremental Builds

Run the clean task and then the build task using the ./gradlew :app:clean :app:build command:

$ ./gradlew :app:clean :app:build

> Task :app:clean
> Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes
> Task :app:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses
> Task :app:test
> Task :app:check
> Task :app:build

BUILD SUCCESSFUL in 1s
8 actionable tasks: 8 executed

No surprise here, Gradle invoked all the tasks needed to build the app, and it was done successfully.

Let’s run the build again:

$ ./gradlew :app:build

> Task :app:compileJava UP-TO-DATE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar UP-TO-DATE
> Task :app:startScripts UP-TO-DATE
> Task :app:distTar UP-TO-DATE
> Task :app:distZip UP-TO-DATE
> Task :app:assemble UP-TO-DATE
> Task :app:compileTestJava UP-TO-DATE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test UP-TO-DATE
> Task :app:check UP-TO-DATE
> Task :app:build UP-TO-DATE

BUILD SUCCESSFUL in 409ms
7 actionable tasks: 7 up-to-date

As we can see, Gradle used the incremental build optimization.

Nothing has changed so Gradle has decided not to re-run some tasks.

Gradle lets us know that inputs and outputs have not changed using the outcome label UP-TO-DATE.

Step 4. Understanding Outcome Labels

There are four outcome labels:

Outcome Label Description

UP-TO-DATE

Task that has been already executed and hasn’t changed (incremental build feature)

SKIPPED

Task was explicitly prevented from running

FROM-CACHE

Task output has been copied to local directory from previous builds in the build cache (caching feature)

NO-SOURCE

Task was not executed because its required inputs were not available

If there is no label, the task was newly executed by Gradle (locally).

We will look at the FROM-CACHE label in the next section.

Next Step: Enabling the Cache >>