Gradle Release Notes

We are excited to announce Gradle 9.7.0-20260620065810+0000 (released 2026-06-20).

This release features 1, 2, ... n, and more.

We would like to thank the following community members for their contributions to this release of Gradle:

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.7.0-20260620065810+0000 by updating the wrapper in your project:

./gradlew :wrapper --gradle-version=9.7.0-20260620065810+0000 && ./gradlew :wrapper

See the Gradle 9.x upgrade guide to learn about deprecations, breaking changes, and other considerations when upgrading to Gradle 9.7.0-20260620065810+0000.

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

New features and usability improvements

Configuration Cache improvements

Gradle provides a Configuration Cache that improves build time by caching the result of the configuration phase and reusing it for subsequent builds.

Isolated Projects improvements

Gradle provides Isolated Projects, an incubating feature that enables parallel project configuration.

Isolated Projects is now incubating

Isolated Projects has graduated from experimental to incubating. It can now be enabled with the stable org.gradle.isolated-projects property and the new --isolated-projects CLI option, dropping the .unsafe. segment from the previous names.

# gradle.properties
org.gradle.isolated-projects=true

The legacy org.gradle.unsafe.isolated-projects property names are now deprecated and will be removed in a future release. They continue to work as aliases for now. See the upgrade guide for the full list of renamed properties.

Isolated Projects now offers three modes for handling constraint violations

Builds adopting Isolated Projects typically contain constraint violations that must be fixed over time. Isolated Projects now offers three modes, each suited to a different stage of that journey:

The opt-in modes can also be combined, for example to complete an IDE sync that concurrency errors would otherwise interrupt:

# gradle.properties
org.gradle.isolated-projects=true
org.gradle.isolated-projects.diagnostics=true
org.gradle.isolated-projects.dangerously-ignore-problems=true

In all modes, the severity of Isolated Projects violations is now independent of the Configuration Cache --configuration-cache-problems=warn flag.

Test reporting and execution

Gradle provides a set of features and abstractions for testing JVM code, along with test reports to display results.

Test framework initialization failures for TestNG, JUnit 4, and JUnit Platform are always logged to the console

Gradle's test logging now surfaces test-framework startup failures from TestNG, JUnit 4, and JUnit Platform even when the default granularity would otherwise hide them.

Previously, when these frameworks failed to initialize (for example, when a TestNG test class threw an exception from its constructor, a JUnit 4 suite could not be started, or a Jupiter @BeforeAll lifecycle hook aborted a container) the failure was silently filtered out by the default granularity. Users would see only > There were failing tests and had to read the XML report to find the underlying cause:

> Task :test FAILED

> There were failing tests. See the report at: file:///.../build/reports/tests/test/index.html

FAILURE: Build failed with an exception.

These framework-startup failures now bypass the granularity filter and are always written to the console by default:

> Task :test

ExampleTest > initializationError FAILED
    framework-startup org.testng.TestNGException: Cannot instantiate class ExampleTest
        at org.testng.internal.ObjectFactoryImpl.newInstance(...)
        ...

The testLogging.events predicate still applies, explicitly silencing FAILED events is honored.

The new TestFailureDetails.isFrameworkFailure() predicate exposes this distinction to Tooling-API and Build-Scan consumers, who may render framework-startup failures differently from ordinary test failures.

See the Test logging section in the Gradle User Manual for more details.

CLI, logging, and problem reporting

Gradle provides an intuitive command-line interface, detailed logs, and a structured problems report that helps developers quickly identify and resolve build issues.

Source locations for more problems

To keep stack trace capture affordable, Gradle attached a source location to only the first 50 problems per build, so builds that report many problems (deprecations especially) left most of them without a file and line.

Gradle now captures a source location for up to 2000 additional problems past that cap. The capture mechanism is far cheaper than a full stack trace, so the added coverage has negligible cost. As a result, the console, the problems report, and the Tooling API show a source location for many more problems than before.

Problems report listing many problems with their source locations

Run with --warning-mode=all to remove the limit and capture a source location for every problem.

See the CLI reference in the Gradle User Manual for more details.

Build authoring improvements

Gradle provides rich APIs for build engineers and plugin authors, enabling the creation of custom, reusable build logic and better maintainability.

Custom timestamps for reproducible archives

Gradle produces reproducible archives by default, using fixed timestamps for all entries. However, some environments, such as those following the SOURCE_DATE_EPOCH specification, require a meaningful, verifiable timestamp rather than a fixed default.

Archive tasks now support a reproducibleFileTimestamp property that lets you set a custom timestamp for every entry in the archive:

import java.time.Instant

tasks.withType<AbstractArchiveTask>().configureEach {
    reproducibleFileTimestamp = providers.environmentVariable("SOURCE_DATE_EPOCH").map {
        Instant.ofEpochSecond(it.toLong()).toEpochMilli()
    }
}

See the Timestamp for files inside archives section in the Gradle User Manual for more details.

Platform and toolchain management

Gradle provides comprehensive support for Native development and JVM languages, featuring automated Toolchains for seamless JDK management.

New lazy element provider for Domain Object Collections

DomainObjectCollection.getElements() returns a Provider<? extends Collection<T>> and acts as an important bridge between the Domain Object Collection and Provider APIs. This API is similar to the existing FileCollection.getElements() method.

The returned provider carries build dependencies, meaning dependencies carried by providers added via addLater and addAllLater are reflected in the returned elements provider:

val container = objects.domainObjectSet(MyType::class.java)
container.addLater(someProvider)

// Lazily access all elements as a Provider
val allElements: Provider<out Collection<MyType>> = container.elements

tasks.register("process") {
    inputs.property("items", allElements)
    doLast {
        println(allElements.get())
    }
}

See the Collections section in the Gradle User Manual for more details.

Core plugin and plugin authoring enhancements

Gradle provides a comprehensive plugin system, including built-in Core Plugins for standard tasks and powerful APIs for creating custom plugins.

Security and infrastructure

Gradle provides robust security features and underlying infrastructure to ensure that builds are secure, reproducible, and easy to maintain.

Tooling and IDE integration

Gradle provides Tooling APIs that facilitate deep integration with modern IDEs and CI/CD pipelines.

General improvements

Gradle provides various incremental updates and performance optimizations to ensure the continued reliability of the build ecosystem.

Kotlin DSL accessor generation is no longer stored in the build cache

Generating the type-safe Kotlin DSL accessors for a project produces Kotlin source files. For some projects those files can be sizeable, but their generation is fast.

Storing and fetching those files adds its own overhead when the Build Cache is in use. That overhead alone is comparable to or higher than the cost of just regenerating the accessors. Gradle therefore no longer stores Kotlin DSL accessor generation in the Build Cache by default.

Builds that use a remote Build Cache will regenerate accessors locally instead of downloading them; in-build deduplication of accessor generation is unaffected. Kotlin DSL script compilation continues to be cached as before.

See the Type-safe model accessors section in the Gradle User Manual for more details.

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.

Documentation and training

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.