Gradle Release Notes

We are excited to announce Gradle 9.0.0-rc-1 (released 2025-06-18).

This release makes Configuration Cache the preferred execution mode and introduces several enhancements to improve its behavior.

Gradle 9.0.0-rc-1 uses Kotlin 2 and Groovy 4, and adopts Semantic Versioning (SemVer) with version numbers in the format MAJOR.MINOR.PATCH.

It also introduces several improvements for build authors, including much better Kotlin DSL script compilation performance, updates to the Gradle API, and a new type for Dependency Graph root nodes that allows detached configurations to resolve dependencies that reference their project.

Gradle 9.0.0-rc-1 includes numerous bug fixes and general improvements. As a major release, it also introduces changes to deprecated APIs and behaviors. For details on what has been removed or updated, refer to the Gradle 8.x upgrade guide.

We would like to thank the following community members for their contributions to this release of Gradle: Aaron Matthis, Adam S, Adam E, Björn Kautler, Daniel Lacasse, Ghost, Eng Zer Jun, EunHyunsu, FlorianMichael, Francisco Prieto, Jake Wharton, Kengo TODA, Kent Kaseda, Madalin Valceleanu, Marc Philipp, Mark S. Lewis, Mycroft Wong, Na Minhyeok, Nelson Osacky, Olivier "Oli" Dagenais, ploober, Radai Rosenblatt, Róbert Papp, Sebastian Schuberth, Victor Merkulov.

Be sure to check out the public roadmap for insight into what's planned for future releases.

Table Of Contents

Upgrade instructions

Switch your build to use Gradle 9.0.0-rc-1 by updating the wrapper in your project:

./gradlew wrapper --gradle-version=9.0.0-rc-1 && ./gradlew wrapper

See the Gradle 8.x upgrade guide to learn about deprecations, breaking changes, and other considerations when upgrading to Gradle 9.0.0-rc-1.

For Java, Groovy, Kotlin, and Android compatibility, see the full compatibility notes.

New features and usability improvements

Configuration Cache improvements

Gradle's Configuration Cache improves build performance by caching and reusing the result of the configuration phase.

Configuration Cache as the preferred execution mode

The Configuration Cache is the preferred mode of execution and is enabled by default in new projects. While not yet required, Gradle encourages adoption by prompting users and gradually phasing out incompatible APIs to prepare for a future where it becomes the only supported mode.

Prompt to enable Configuration Cache

If your build has no known Configuration Cache incompatibilities but doesn't yet have the Configuration Cache enabled, Gradle will suggest enabling it at the end of the build:

Configuration Cache prompt to enable

Some issues can only be detected when the Configuration Cache is active, so additional refinements may still be needed to fully adopt it.

If you're not ready to invest time in this yet, you can suppress the suggestion by explicitly disabling the feature in your gradle.properties file:

org.gradle.configuration-cache=false

Graceful fallback from Configuration Cache mode

Gradle falls back to non-Configuration Cache mode automatically when encountering unsupported features, instead of failing the build.

This includes:

After running a build, the reason for the fallback can be found in the Configuration Cache report.

Other notable Configuration Cache updates

Additional updates for the Configuration Cache include:

Gradle requires Java Virtual Machine (JVM) version 17 or higher to run

Gradle requires a Java Virtual Machine (JVM) version 17 or higher to start the Gradle daemon.

If you need to build with older JVM versions, you can specify a separate JDK toolchain in the build definition by using toolchains. Gradle still supports compiling, testing and running other JVM-based tools with 8 and higher.

See the Compatibility Matrix for more information.

Update to Kotlin 2

Gradle embeds the latest stable release of Kotlin 2.1.x runtime and uses Kotlin language version 2.1. This marks a shift from Gradle 8.x, which embedded Kotlin 2.0 starting in 8.11 but continued to use Kotlin language version 1.8 for compatibility.

For a comprehensive overview of what’s new, see the Kotlin 2.1.0 and Kotlin 2.0.0 release notes for full details.

Gradle uses Kotlin for build logic, which includes:

As a result, some behavior has changed, most notably the new K2 compiler and JSpecify. If you're upgrading, review the Gradle 8.x upgrade guide for migration details.

Update to Groovy 4

Gradle embeds the latest stable release of Groovy 4.0, a major upgrade from the Groovy 3.0 version used in Gradle 7 and 8.

This update introduces a range of new features and improvements to the Groovy language. For a comprehensive overview of what’s new, see the Groovy 4.0 release notes for full details.

Gradle uses Groovy for build logic, which includes:

Some behavior has changed between Groovy 3.0 and 4.0. If you're upgrading, review the Gradle 8.x upgrade guide for migration details.

Semantic Versioning for Gradle releases

Starting with Gradle 9, all Gradle releases follow the Semantic Versioning (SemVer) specification.

Version numbers are expressed as MAJOR.MINOR.PATCH, whereas previous minor releases omitted the patch segment (e.g., 8.5 instead of 8.5.0).

This change only applies to new releases and does not retroactively affect older versions or backports. Additionally, internal code and features marked with @Incubating are not considered part of the public API and may change in minor releases.

Build authoring improvements

Gradle provides rich APIs for plugin authors and build engineers to develop custom build logic.

Kotlin build script compilation avoidance

Gradle speeds up feedback loops when editing build logic by avoiding unnecessary recompilation of Kotlin DSL (.kts) build scripts. This reduces build times and improves developer productivity.

The improvement comes from significantly better detection of ABI (Application Binary Interface) changes, made possible by using Kotlin’s built-in ABI fingerprinting instead of Gradle’s previous internal mechanism. This brings major performance benefits, especially in builds that use inline functions, which were not handled efficiently before.

For example, in the Gradle build itself, non-ABI changes to build logic result in up to a 60% reduction in configuration time by avoiding unnecessary script recompilation.

Reduction in unnecessary script recompilation

Gradle API uses JSpecify Nullability annotations

Since Gradle 5.0 we've been using annotations from JSR-305 to make the nullness of type usages explicit for the Gradle API. Starting with Gradle 9, the Gradle API is annotated using JSpecify instead.

Kotlin 2.1, when combined with JSpecify annotations in the Gradle API, introduces stricter nullability handling. For more details and potential breakages, see the dedicated upgrading guide section.

Support for major and minor version specification in Gradle Wrapper

Gradle supports specifying only a major or minor version when configuring the wrapper.

For example, the following resolves to the latest 9.x.y release:

./gradlew wrapper --gradle-version=9

While the following resolves to the latest 9.1.x release:

./gradlew wrapper --gradle-version=9.1

This feature requires Gradle 9.0.0 or later. Earlier versions don’t follow full semantic versioning and may misinterpret partial versions (e.g., 8.12 might refer to 8.12 (because it's an exact version) and 8.12.1 (semantically the latest version for 8.12).

Gradle’s version information endpoint has been extended to support this behavior. For instance, https://services.gradle.org/versions/9 lists all versions of Gradle with major version 9.

Archive tasks produce reproducible archives by default

Archive tasks such as Jar, Ear, War, Zip, Tar, and AbstractArchiveTask produce reproducible archives by default. This means that generated archives have reproducible file order and preconfigured file timestamps and permissions. As a result archives generated from the same inputs will be identical byte-for-byte.

This change may affect builds that rely on non-deterministic archive characteristics like file order, file system timestamps, or file system permissions, or file executable bit.

For more information, see the upgrading guide section.

Detached configurations can resolve dependencies on their own project

Detached configurations are able to resolve dependencies that reference their own project.

To do this, Gradle introduces a new subtype of ComponentIdentifier called RootComponentIdentifier, which represents the root node of a resolved dependency graph.

When a configuration is resolved, it is first transformed into a synthetic variant. This variant is owned by a synthetic root component, which is identified using RootComponentIdentifier. The root component itself exists only to own the root variant.

Dependency graphs resolved from detached configurations and buildscript configurations will have a component identified by a RootComponentIdentifier at the root of their graph. This lets Gradle differentiate between a detached configuration and the project it lives in.

Resolved project configurations will continue to have their root component live within the project's component and identified by a ProjectComponentIdentifier. In future Gradle versions, all configurations, including those declared inside projects (non-detached), will be owned by a synthetic root component identified by a RootComponentIdentifier.

Documentation improvements

Gradle Best Practices

In partnership with JetBrains and Google, we've launched a new Gradle Best Practices guide to help you avoid common pitfalls and write more maintainable, performant builds. These recommendations consolidate community knowledge and Gradle team insights into a single, growing resource. The current version covers best practices in dependency declarations, build structure, task authoring, and more.

For more information, check out the Gradle Best Practices blog post.

Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to backward 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.

The following operator functions in DependencyHandlerScope are now considered stable:

The following operator functions in DependencyConstraintHandlerScope are now considered stable:

The following top-level functions in DependencyHandlerExtensions are now considered stable:

The following top-level functions in KotlinDependencyExtensions are now considered stable:

The following functions are now considered stable:

Fixed issues

Known issues

Known issues are problems that were discovered post-release that are directly related to changes made in this release.

External contributions

We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.

Reporting problems

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 if 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.