Gradle Release Notes

The Gradle team is excited to announce Gradle 8.3.

This release features the support for persistent Java compiler daemons to speed up Java compilation. Gradle will also use less memory for dependency resolution. The effect is significant, particularly for large builds such as Android builds.

Gradle now supports running on Java 20.

For Kotlin DSL, build authors can try out the Kotlin K2 compiler for build logic with some limitations. See the Kotlin DSL dedicated section for more information.

This release also brings several usability improvements, including better CodeNarc output, a dry run mode for test execution, improved output for task options, and upgraded SSL support.

We would like to thank the following community members for their contributions to this release of Gradle: Adam, Ahmed Ehab, Aurimas, Baptiste Decroix, Björn Kautler, Borewit, Korov, Mohammed Thavaf, Patrick Brückner, Philip Wedemann, Róbert Papp, Shi Chen, Tony Robalik

Table Of Contents

Upgrade instructions

Switch your build to use Gradle 8.3 by updating your wrapper:

./gradlew wrapper --gradle-version=8.3

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

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

New features and usability improvements

Faster Java compilation

When compiling Java code, Gradle uses worker processes to run the Java compiler as a compiler daemon. This allows the Java compiler to "warm up" and compile faster after a few uses. Reusing compiler daemons within a single build invocation speeds up overall build performance as every compile task can potentially execute more quickly.

In previous Gradle releases, the compiler daemons were shut down at the end of the build. This caused every build to incur the cost of starting the compiler daemon and warming up the compiler. These start-up costs contributed to a large portion of overall build time when incrementally compiling a few source files.

Starting with this release, Gradle attempts to keep Java compiler daemons alive after the end of the build, so that subsequent builds are faster.

Gradle will stop compiler daemons only when Gradle needs to free up resources.

The performance benefit these persistent compiler daemons introduce can vary depending on a wide range of factors. However, Gradle's internal performance tests show up to a 30% build time improvement for builds that are dominated by compiling Java sources.

No configuration changes are required to enable this feature. Persistent compiler daemons are currently supported on Linux and MacOS. Support on the Windows platform will follow in a subsequent release.

Full Support for Java 20

Gradle 8.1 supported compiling and testing with Java 20 using Java toolchains, but running Gradle itself on Java 20 was not yet supported.

With this release, Gradle now fully supports compiling, testing and running on Java 20.

See the full compatibility documentation for details.

Reduced memory consumption

Gradle is now using less memory during dependency resolution. This should benefit most builds, but the gains will be more substantial for the IDE sync process, particularly for builds doing lots of dependency resolution.

Performance results measured with syncing a large Android project with the Android Studio Giraffe.

memory consumption graph

Although the changes should benefit most builds, we are aware of a regression affecting builds that rely a lot on detached configurations. This specific case will be fixed in a later release.

Kotlin DSL improvements

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.

Kotlin DSL has received substantial improvements in recent releases, leading to the announcement that Kotlin DSL is Now the Default for New Gradle Builds. This release brings another series of improvements.

Simplified plugin request when needing the embedded Kotlin version

Gradle allows using kotlin(String) as a shortcut to apply plugins in the org.jetbrains namespace. However this requires specifying the version of the plugin to apply.

Starting with this Gradle version, you can use embeddedKotlin() instead:

plugins {
    embeddedKotlin("plugin.serialization")
}

This will result in applying the plugin with a version matching the Kotlin version embedded in Gradle.

Build scripts now accept dependencies compiled with Kotlin K2 compiler

As announced by the Kotlin team, the K2 compiler is going stable in Kotlin 2.0.

Starting with Kotlin 1.9.0-RC and until the release of Kotlin 2.0, you can easily test the K2 compiler in your Gradle projects. In order to do so, add -Pkotlin.experimental.tryK2=true to your command line invocations or add it to your gradle.properties file:

kotlin.experimental.tryK2=true

Setting this Gradle property also sets the language version to 2.0.

Starting with this version of Gradle, the compilation of .gradle.kts build scripts accepts dependencies compiled with Kotlin K2 compiler. This makes it possible to try out K2 in builds that use Kotlin 1.9 and have Kotlin code in buildSrc or in included builds for build logic.

Note that if you use the kotlin-dsl plugin in your build logic, you will need to explicitly set the Kotlin language version to 2.0:

tasks.withType<KotlinCompile>().configureEach {
    compilerOptions { 
        apiVersion = KotlinVersion.KOTLIN_2_0
        languageVersion = KotlinVersion.KOTLIN_2_0 
    }
}

Note that at this stage, K2 doesn't support scripting, so it will not work with precompiled script plugins.

Specify file permissions conveniently

Setting file permissions as UNIX mode values is inconvenient since Kotlin doesn’t support octal numeric literals: instead of mode = 0755 one has to write mode = "755".toInt(radix = 8).

There is now a better API for setting file permissions and extra convenience methods for UNIX-style values.

tasks.register<Copy>("copy") { 
    // details omitted 
    filePermissions {
        user {
            read = true
            execute = true
        }
        other.execute = false
    }
    dirPermissions {
        unix("r-xr-x---")
    }
}

The embedded Kotlin has been upgraded to 1.9.0

The embedded Kotlin has been updated from 1.8.20 to Kotlin 1.9.0, unblocking the support for running on Java 20.

The Kotlin language and API levels for the Kotlin DSL are still set to 1.8 for backward compatibility. See the release notes for Kotlin 1.8.22 and Kotlin 1.8.21.

Configuration cache

The configuration cache improves build time by caching the result of the configuration phase and reusing it for subsequent builds. This feature can significantly improve build performance.

Temporarily opting out of stricter configuration inputs detection

To ensure correctness, the configuration cache detects undeclared inputs when plugins or build logic perform file system checks such as File.exists() or File.isFile(). However, not all plugins are updated to properly declare all inputs, leading to cache misses and suboptimal performance.

Configuration cache now has an opt-out option for temporarily ignoring such undeclared inputs.

This option mitigates undesired configuration cache misses until the plugins are properly updated.

See the corresponding section in the user guide for details.

The configuration cache summary is no longer produced if no problems are encountered

When the configuration cache feature is enabled, a configuration cache report is produced at path-to-project/build/reports/configuration-cache/<hash>/configuration-cache-report.html if any configuration cache-related problems are found, or if any configuration inputs are detected.

In previous releases, when a report was produced (because problems were found, or inputs were detected), the build output always included a summary conveying the number of problems found, and a link to the configuration cache report:

0 problems were found storing the configuration cache.

See the complete report at file:///path-to-project/build/reports/configuration-cache/<hash>/configuration-cache-report.html

Starting with this release, the summary will only be produced if the report includes any problems. The summary will be omitted if the report only contains information on the configuration inputs.

Note the report is still generated if any problems are found or inputs detected; only the summary is omitted from the console output.

It is possible to force the summary to be produced even if no configuration cache-related problems are found by specifying the --info option.

Improved CodeNarc output

The CodeNarc plugin produces IDE-clickable links when reporting failures to the console. The CodeNarc task also produces clickable links in failure messages to human-readable reports when multiple reports are enabled.

codenarc error in console with link

The HTML report generated by CodeNarc has been updated to produce violation reports with sortable columns.

codenarc html report

Dry run mode for test execution

When testing your project, it may be useful to check which of the tests that you selected would run without actually executing them, especially when using test filtering.

This release introduces a test dry run mode, which can be enabled by either the --test-dry-run command-line option or via the dryRun property.

This mode is compatible with the JUnit and TestNG frameworks.

Group opposite boolean build and task options together

In previous Gradle releases, the console output of the help task rendered options in alphabetical order. This made it harder to see boolean options that have opposing settings.

For better readability, this has been changed to group opposite boolean options together.

Disable options are now sorted after their enable options. For example, the options --daemon, --no-daemon, --no-parallel, --parallel are now rendered in the following order:

--daemon
--no-daemon
--parallel
--no-parallel

See the task options user manual section for more information.

Maven toolchain declarations with environment variables are now supported

Using toolchains is the recommended way of specifying Java versions for JVM projects. By default, Gradle automatically detects local JRE/JDK installations so no further configuration is required by the user. One of the auto-detection formats that Gradle supports is Maven Toolchain specification.

With this Gradle release, if you rely on the integration with Maven toolchain definitions, Gradle now supports the use of environment variables placeholders inside toolchain.xml files. The placeholder will be resolved by looking at environment variables known to the Gradle build.

SSL improvements for non-standard keystores and truststores

Previously, Gradle exhibited limitations when interfacing with non-standard keystores and truststores. This affected users on Linux systems with FIPS enabled and also Windows users who were storing certificates in the Trusted Root Certification Authorities store.

SSL context creation has been improved to be more aligned with the default implementation and to support these cases.

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