Configuration Cache Status
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.
See gradle/gradle#13510.
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.
See gradle/gradle#13506.
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.
See gradle/gradle#25979.
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.
See gradle/gradle#20969.
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 areadObject
method to control exactly which information to store; -
a
writeObject
method with no correspondingreadObject
;writeObject
must eventually callObjectOutputStream.defaultWriteObject
; -
a
readObject
method with no correspondingwriteObject
;readObject
must eventually callObjectInputStream.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 buttransient
fields serializable; -
the following methods of
ObjectOutputStream
are not supported and will throwUnsupportedOperationException
:-
reset()
,writeFields()
,putFields()
,writeChars(String)
,writeBytes(String)
andwriteUnshared(Any?)
.
-
-
the following methods of
ObjectInputStream
are not supported and will throwUnsupportedOperationException
:-
readLine()
,readFully(ByteArray)
,readFully(ByteArray, Int, Int)
,readUnshared()
,readFields()
,transferTo(OutputStream)
andreadAllBytes()
.
-
-
validations registered via
ObjectInputStream.registerValidation
are simply ignored; -
the
readObjectNoData
method, if present, is never invoked;
See gradle/gradle#13588.
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:
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:
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.
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:
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. |
See gradle/gradle#22879.
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.
See gradle/gradle#24085.
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.
See gradle/gradle#33772.