We are excited to announce Gradle 9.9.0-20261004003900+0000 (released 2026-10-04).
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: devareddy05.
Be sure to check out the public roadmap for insight into what's planned for future releases.
Switch your build to use Gradle 9.9.0-20261004003900+0000 by updating the wrapper in your project:
./gradlew :wrapper --gradle-version=9.9.0-20261004003900+0000 && ./gradlew :wrapper
See the Gradle 9.x upgrade guide to learn about deprecations, breaking changes, and other considerations when upgrading to Gradle 9.9.0-20261004003900+0000.
For Java, Groovy, Kotlin, and Android compatibility, see the full compatibility notes.
Isolated Projects is an incubating performance feature that safely runs project configuration in parallel, significantly reducing configuration time in many scenarios, including IDE sync and CI builds.
Gradle provides a Configuration Cache that improves build time by caching the result of the configuration phase and reusing it for subsequent builds.
Gradle provides a set of features and abstractions for testing JVM code, along with test reports to display results.
Gradle provides an intuitive command-line interface, detailed logs, and a structured problems report that helps developers quickly identify and resolve build issues.
The build progress shown in the terminal is now also reported to the Windows taskbar when running in Windows Terminal 1.6 or later, in addition to ConEmu, Ghostty, kitty and iTerm2. This makes it easy to see how far a long-running build has progressed while the terminal window is in the background, and it also works in WSL shells hosted by Windows Terminal.
See the Rich console section in the Gradle User Manual for more details.
The incubating Problems API now provides a predefined hierarchy of problem groups, available from the Problems service as problems.groups. Plugins report into the matching predefined group or add a subgroup below one. The types of the hierarchy enforce placement:
problems.reporter.report(problems.groups.compilation.java.problemId("Unused import")) {}
problems.reporter.report(problems.groups.transformation.group("KMP").problemId("Bundle failed")) {}
Predefined groups are documented with a description of what belongs in them, giving consumers of problem reports a documented set of group names to navigate, filter, and aggregate the problems plugins report. On the console, problems now show the chain of groups they belong to, for example Unused import (in Compilation > Java). The existing ProblemGroup.create() and ProblemId.create() methods keep working; migrating to the predefined groups is recommended.
Gradle's own compilation problems now use the predefined groups: Java compiler diagnostics and compiler initialization failures report into Compilation > Java, a missing tools.jar for the Groovy compiler into Compilation > Groovy, and Groovy DSL script compilation failures into Gradle > DSL Evaluation. Both the group and the name of these problem ids changed, so Tooling API and report consumers that match on the old ids need to update. For example, compilation:java:initialization-failed is now Compilation:Java:Compiler initialization failed. The console heading for a failed compiler start changes with it, from Java compilation initialization error to Compiler initialization failed. Java compiler diagnostics are named after the kind of diagnostic, for example Cannot find symbol instead of the javac code compiler.err.cant.resolve.location; the compiler's message stays in the problem's contextual label.
See the Predefined Problem Groups section in the Gradle User Manual for more details.
Gradle provides rich APIs for build engineers and plugin authors, enabling the creation of custom, reusable build logic and better maintainability.
wrapper task preserves customized propertiesThe wrapper task now preserves values customized in an existing gradle-wrapper.properties file when they are not explicitly configured on the task. Preserved values include the network timeout, URL validation, retries, retry backoff, and the distribution and archive paths and bases. Explicit task configuration still takes precedence.
For example, validateDistributionUrl=false (previously set by running ./gradlew :wrapper --no-validate-url) now persists when the wrapper is regenerated.
User-declared Wrapper tasks now also write the default network timeout, retry count, and retry backoff when those properties are not otherwise configured.
See the Preserving Existing Wrapper Properties section in the Gradle User Manual for more details.
Gradle provides a flexible dependency management engine for declaring, resolving, and verifying the dependencies your build needs.
Gradle provides comprehensive support for JVM languages, featuring automated Toolchains for seamless JDK management.
Gradle provides a comprehensive plugin system, including built-in Core Plugins for standard tasks and powerful APIs for creating custom plugins.
Sync can empty its destination when its source is emptyA Sync task whose source contains no files and no directories, by default, does not run, so its destination directory is not synchronized. What is left in the destination then depends on whether it is a build-owned directory: if it is, the destination is cleaned up; otherwise it keeps the files the source no longer contains.
Setting the new skipWhenSourceIsEmpty property to false makes the task run in that case as well, so that an empty source empties the destination directory:
tasks.named<Sync>("mySync") {
skipWhenSourceIsEmpty = false
}
Sync always deletes the entire contents of its destination directory, not only the files it previously copied there. With skipWhenSourceIsEmpty disabled, that also happens when the source is empty - including when it is empty by mistake - so disable it only where nothing other than the task writes to the destination, and use preserve { ... } to retain anything the task does not manage.
See Synchronizing from an empty source in the user manual for more details.
Gradle provides robust security features and underlying infrastructure to ensure that builds are secure, reproducible, and easy to maintain.
Gradle provides Tooling APIs that facilitate deep integration with modern IDEs and CI/CD pipelines.
Gradle continuously improves build performance through caching, parallelism, and reduced overhead across all phases of the build.
Gradle provides various incremental updates and performance optimizations to ensure the continued reliability of the build ecosystem.
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.
dependencies block APIThe remaining incubating parts of the API for custom dependencies blocks have been promoted:
add(ProviderConvertible) and the bundle(...) methods in DependencyCollectorconstraint(Provider) and constraint(ProviderConvertible) in Dependenciesmodify(ProviderConvertible) in DependencyModifierDependencyConstraintFactoryPlatformDependencyModifiers and TestFixturesDependencyModifiersKnown 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 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.