The Gradle team is excited to announce Gradle 8.4.
This release features several improvements for JVM-based projects. Java 21 is now supported for compiling, testing, and running such projects. Faster Java compilation with persistent compiler daemons now also works on Windows. This release also brings a simpler way to create dependency configurations for specific roles. For more improvements for JVM-based projects, see the full release notes below.
Kotlin DSL, which recently became the default DSL for new projects, continues to receive improvements. The Kotlin version embedded in Gradle has been updated to Kotlin 1.9.10. The simple property assignment with the =
operator has been promoted to stable. In addition, the reference documentation for the Kotlin DSL now provides links back to sources hosted on GitHub.
In addition, this release addresses two security vulnerabilities:
Check their details to learn about workarounds if you are not able to upgrade to this version.
We would like to thank the following community members for their contributions to this release of Gradle: Ahmed Ehab, Andrei Rybak, Baptiste Decroix, Björn Kautler, Cesar de la Vega, Ganavi Jayaram, Gaurav Padam, hwanseok, J.T. McQuigg, Jakub Chrzanowski, Jendrik Johannes, kackey0-1, Konstantin Gribov, Pratik Haldankar, Qinglin, Sebastian Schuberth, Thad House, valery1707, Vladimir Sitnikov, wuyangnju, Yanming Zhou, Yanshun Li, Yusuke Uehara, zeners
Switch your build to use Gradle 8.4 by updating your wrapper:
./gradlew wrapper --gradle-version=8.4
See the Gradle 8.x upgrade guide to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 8.4.
For Java, Groovy, Kotlin and Android compatibility, see the full compatibility notes.
Gradle now supports using Java 21 for compiling, testing, and starting other Java programs. This can be accomplished using toolchains.
Currently, you cannot run Gradle on Java 21 because Kotlin lacks support for JDK 21. However, support for running Gradle with Java 21 is expected in future versions.
Gradle 8.3 made Java compilation faster, by keeping compiler daemons alive between builds. Gradle's internal performance tests show up to a 30% build time improvement for builds that are dominated by compiling Java sources. Until now, this optimization was only supported on Linux and macOS.
With this release, persistent Java compiler daemons are also supported on Windows. No configuration changes are required to enable this feature.
Gradle provides a flexible dependency management engine that allows build engineers and plugin authors to distinguish between the needs of consumers and producers. Configurations involved in dependency management can have three different distinct roles detailed in Resolvable and consumable configurations.
The ConfigurationContainer now exposes three concrete Configuration
roles:
Dependencies cannot be declared on configurations created with the consumable
and resolvable
factory methods.
Previously, the only way to specify a Configuration
's role would be by mutating the canBeConsumed
, canBeResolved
, and canBeDeclared
properties.
Now, new factory methods allow the container to create Configuration
s explicitly requesting one of these roles.
Build engineers and plugin authors can ensure that their Configuration
s are used only for their intended purpose since Configuration
s created using these factory methods cannot be mutated. A configuration with one role can never perform the functions of another.
Gradle core plugins will migrate their configurations to use role-locked configurations in Gradle 9.0. Furthermore, in future versions of Gradle, the ability to mutate roles or create Configuration
s without the factory methods will become increasingly restricted.
Code which previously used the mutable role properties:
configurations {
create("implementation") {
isCanBeDeclared = true // Defaults to true
isCanBeResolved = false
isCanBeConsumed = false
}
create("runtimeClasspath") {
isCanBeDeclared = false
isCanBeResolved = true // Defaults to true
isCanBeConsumed = false
extendsFrom(configurations["implementation"])
}
create("runtimeElements") {
isCanBeDeclared = false
isCanBeResolved = false
isCanBeConsumed = true // Defaults to true
extendsFrom(configurations["implementation"])
}
}
May now use the factory methods:
configurations {
dependencyScope("implementation")
resolvable("runtimeClasspath") {
extendsFrom(configurations["implementation"])
}
consumable("runtimeElements") {
extendsFrom(configurations["implementation"])
}
}
Gradle's Kotlin DSL provides an enhanced editing experience in supported IDEs compared to the traditional Groovy DSL — auto-completion, smart content assist, quick access to documentation, navigation to source, and context-aware refactoring.
The embedded Kotlin has been updated from 1.9.0 to Kotlin 1.9.10.
The simple property assignment with the =
operator has been promoted to stable.
The Kotlin DSL Reference guide now contains links to the source code of all Kotlin and Java types, functions, and properties. The links point to GitHub and are specific to the version of the code the guide is documenting.
Gradle uses worker processes to run code quality tools like Checkstyle, CodeNarc, and PMD. On larger code bases, these workers can require more memory than what Gradle provides by default.
In this release, Gradle supports configuring the workers' minimum and maximum heap sizes on all code-quality tasks, so that larger projects can configure memory required to run their builds. These options are available on the different tasks for these tools.
The default Checkstyle HTML report has been improved to show only the files with violations and correctly link to those files from the summary table.
The report also contains the version of Gradle and Checkstyle used to analyze the sources.
It is now possible to use JetBrains as a known JVM vendor of Toolchains when referring to JetBrains Runtime when using :
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
vendor.set(JvmVendorSpec.JETBRAINS)
}
}
The filter
method has been added to Provider
and Property
to allow filtering of a value.
val property = objects.property<String>()
property.set("foobar")
val matches = property.filter { it.contains("foo") } // still contains "foo"
val doesntMatch = property.filter { it.contains("baz") } // is empty
Note that filter
is evaluated lazily, so the predicate is only evaluated when the value is queried.
Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to backwards compatibility. See the User Manual section on the “Feature Lifecycle” for more information.
The following are the features that have been promoted in this Gradle release.
Gradle 8.1 introduced a simpler way to assign values to lazy property types in Kotlin scripts using the =
operator instead of the set()
method. This new assignment operator was enabled by default in 8.2 and in this release it is marked stable.
interface Extension {
val description: Property<String>
}
// register "extension" with type Extension
extension {
// Using the set() method call
description.set("Hello Property")
// Using lazy property assignment
description = "Hello Property"
}
For more information, see Kotlin DSL Primer.
Known issues are problems that were discovered post release that are directly related to changes made in this release.
We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.
If you find a problem with this release, please file a bug on GitHub Issues adhering to our issue guidelines. If you're not sure you're encountering a bug, please use the forum.
We hope you will build happiness with Gradle, and we look forward to your feedback via Twitter or on GitHub.