This feature is not enabled by default.

Supported Plugins

The Configuration Cache introduces new requirements for plugin implementations. As a result, both Core Gradle plugins and Community Plugins need to be adjusted to ensure compatibility.

This section provides details on the current support in:

Core Gradle Plugins

Most Core Gradle Plugins support configuration caching at this time:

JVM languages and frameworks

Native languages

Packaging and distribution

 Code analysis

 IDE project files generation

Utility

Supported plugin

Partially supported plugin (tasks always disable configuration caching)

⚠*

Partially supported plugin (some features may disable configuration caching)

Community Plugins

Please refer to issue gradle/gradle#13490 to learn about the status of Community Plugins.

The two most popular ecosystem plugins are supported:

  • Android Gradle Plugin

  • Kotlin Gradle Plugin

Not Yet Implemented

Support for configuration caching with certain Gradle features is not yet available. These features will be supported in future Gradle releases.

Sharing the Configuration Cache

The Configuration Cache is currently stored locally only. It can be reused by both hot and cold local Gradle daemons, but it cannot be shared between developers or CI machines.

Source Dependencies

Support for source dependencies is not yet implemented. When using this feature, the build will not fail, and no problems will be reported, but the Configuration Cache will be automatically disabled.

Using a Java Agent with Builds run using TestKit

When running builds using TestKit, the Configuration Cache can interfere with Java agents, such as the Jacoco agent, that are applied to these builds.

Fine-grained Tracking of Gradle Properties as Build Configuration Inputs

Currently, all external sources of Gradle properties—such as gradle.properties files (both in project directories and in the GRADLE_USER_HOME), environment variables, system properties that set properties, and properties specified via command-line flags—are considered build configuration inputs, regardless of whether they are actually used during configuration.

However, these sources are not included in the Configuration Cache report.

Java Object Serialization

Gradle allows objects that support the Java Object Serialization protocol to be stored in the Configuration Cache.

The implementation is currently limited to serializable classes that either implement the java.io.Externalizable interface, or implement the java.io.Serializable interface and define one of the following combination of methods:

  • a writeObject method combined with a readObject method to control exactly which information to store;

  • a writeObject method with no corresponding readObject; writeObject must eventually call ObjectOutputStream.defaultWriteObject;

  • a readObject method with no corresponding writeObject; readObject must eventually call ObjectInputStream.defaultReadObject;

  • a writeReplace method to allow the class to nominate a replacement to be written;

  • a readResolve method to allow the class to nominate a replacement for the object just read;

The following Java Object Serialization features are not supported:

  • the serialPersistentFields member to explicitly declare which fields are serializable; the member, if present, is ignored; the Configuration Cache considers all but transient fields serializable;

  • the following methods of ObjectOutputStream are not supported and will throw UnsupportedOperationException:

    • reset(), writeFields(), putFields(), writeChars(String), writeBytes(String) and writeUnshared(Any?).

  • the following methods of ObjectInputStream are not supported and will throw UnsupportedOperationException:

    • readLine(), readFully(ByteArray), readFully(ByteArray, Int, Int), readUnshared(), readFields(), transferTo(OutputStream) and readAllBytes().

  • validations registered via ObjectInputStream.registerValidation are simply ignored;

  • the readObjectNoData method, if present, is never invoked;

Accessing top-level Methods and Variables of a Build Script at Execution Time

A common approach to reuse logic and data in a build script is to extract repeating bits into top-level methods and variables. However, calling such methods at execution time is not currently supported if the Configuration Cache is enabled.

For builds scripts written in Groovy, the task fails because the method cannot be found. The following snippet uses a top-level method in the listFiles task:

build.gradle
def dir = file('data')

def listFiles(File dir) {
    dir.listFiles({ file -> file.isFile() } as FileFilter).name.sort()
}

tasks.register('listFiles') {
    doLast {
        println listFiles(dir)
    }
}

Running the task with the Configuration Cache enabled produces the following error:

Execution failed for task ':listFiles'.
> Could not find method listFiles() for arguments [/home/user/gradle/samples/data] on task ':listFiles' of type org.gradle.api.DefaultTask.

To prevent the task from failing, convert the referenced top-level method to a static method within a class:

build.gradle
def dir = file('data')

class Files {
    static def listFiles(File dir) {
        dir.listFiles({ file -> file.isFile() } as FileFilter).name.sort()
    }
}

tasks.register('listFilesFixed') {
    doLast {
        println Files.listFiles(dir)
    }
}

Build scripts written in Kotlin cannot store tasks that reference top-level methods or variables at execution time in the Configuration Cache at all. This limitation exists because the captured script object references cannot be serialized. The first run of the Kotlin version of the listFiles task fails with the Configuration Cache problem.

build.gradle.kts
val dir = file("data")

fun listFiles(dir: File): List<String> =
    dir.listFiles { file: File -> file.isFile }.map { it.name }.sorted()

tasks.register("listFiles") {
    doLast {
        println(listFiles(dir))
    }
}

To make the Kotlin version of this task compatible with the Configuration Cache, make the following changes:

build.gradle.kts
object Files { (1)
    fun listFiles(dir: File): List<String> =
        dir.listFiles { file: File -> file.isFile }.map { it.name }.sorted()
}

tasks.register("listFilesFixed") {
    val dir = file("data") (2)
    doLast {
        println(Files.listFiles(dir))
    }
}
1 Define the method inside an object.
2 Define the variable in a smaller scope.

Using Build Services to Invalidate the Configuration Cache

Currently, it is impossible to use a provider of BuildService or provider derived from it with map or flatMap as a parameter for the ValueSource, if the value of the ValueSource is accessed at configuration time. The same applies when such a ValueSource is obtained in a task that executes as part of the configuration phase, for example tasks of the buildSrc build or included builds contributing plugins.

Note that using a @ServiceReference or storing BuildService in an @Internal-annotated property of a task is safe.

Generally speaking, this limitation makes it impossible to use a BuildService to invalidate the Configuration Cache.

Using Arbitrary Providers as Build Events Listeners

The build event listener registration method BuildEventsListenerRegistry.onTaskCompletion accepts arbitrary providers of any OperationCompletionListener implementations. However, only providers returned from BuildServiceRegistry.registerIfAbsent or BuildServiceRegistration.getService are currently supported when the Configuration Cache is used. Starting with Gradle 9, using other kinds of providers (including even registerIfAbsent(…​).map { it }) results in a Configuration Cache problem being emitted. Prior to that, such providers were silently ignored.

Check the adoption guide to learn how to temporarily suppress these problems if discarded listeners do not affect your build.