Gradle Release Notes

Version 7.5-rc-2

The Gradle team is excited to announce Gradle 7.5-rc-2.

This release includes building code and running Gradle with Java 18, building code with Groovy 4, much more responsive continuous builds, improved diagnostics for dependency resolution, as well as configuration cache improvements for better performance, Adoptium toolchain provisioning for JVM, and more.

We would like to thank the following community members for their contributions to this release of Gradle: Michael Bailey, Josh Kasten, Marcono1234, mataha, Lieven Vaneeckhaute, kiwi-oss, Stefan Neuhaus, George Thomas, Anja Papatola, Björn Kautler, David Burström, Vladimir Sitnikov, Roland Weisleder, Konstantin Gribov, David Op de Beeck, aSemy, Rene Groeschke, Jonathan Leitschuh, Aurimas Liutikas, Jamie Tanna, Xin Wang, Atsuto Yamashita, Taeik Lim, Peter Gafert, Alex Landau, Jerry Wiltse, Tyler Burke, Matthew Haughton, Filip Daca, Simão Gomes Viana, Vaidotas Valuckas, Edgars Jasmans, Tomasz Godzik, Jeff, Lajos Veres

Table Of Contents

Upgrade instructions

Switch your build to use Gradle 7.5-rc-2 by updating your wrapper:

./gradlew wrapper --gradle-version=7.5-rc-2

See the Gradle 7.x upgrade guide to learn about deprecations, breaking changes and other considerations when upgrading to Gradle 7.5-rc-2.

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

New features and usability improvements

Support for Java 18

Gradle now supports running on and building with Java 18.

Support for Groovy 4

Gradle now supports building software using Groovy 4.0. Note that Groovy DSL buildscripts still use Groovy 3.

Scala Zinc has been updated

The default Scala Zinc version was updated to 1.6.1.

Zinc is the Scala incremental compiler that allows Gradle to always compile the minimal set of files needed by the current file changes. It takes into account which methods are being used and which have changed, which means it’s much more granular than just interfile dependencies.

Continuous Build is much more responsive on Windows and macOS with Java 9+

Continuous Build automatically re-executes the build with the same requested tasks when inputs change. This allows for continuous feedback during development.

Because of the internal changes in the JDK, Continuous Build did not work well on Windows and macOS on Java 9 and higher. It could take up to 10 seconds to detect a change and trigger a build.

Now Gradle picks up changes nearly instantly on Windows and macOS for all Java versions as well, making Continuous Build respond quickly on all major operating systems. This is because Gradle now uses its own robust and natively implemented file system watching system instead of relying on the generic API in the JDK.

Improved diagnostic reports for dependency resolution

Outgoing Variants

The outgoingVariants report now provides additional information that allows further insight into variant aware dependency resolution results.

This report is useful when determining why a particular variant of this producer project was selected by another consumer project when the producer depends upon the consumer. Run the report from the producer project, to list every variant built by it (including secondary variants only visible to other local projects). The output contains the capabilities and attributes present on each variant of the producer, along with other information detailed below. This output can be compared against the output of the new resolvableConfigurations report run in the consumer.

outoingVariants output

  1. Descriptions are now printed for secondary variants, if present.
  2. Configurations using @Incubating attributes are marked with an (i).
  3. The legend at the bottom of the report clarifies the usage of secondary variants.

See the OutgoingVariantsReport DSL reference for more details.

Description available on secondary variants

When defining secondary variants, which are variants available only to other local Gradle projects, there is a new ConfigurationVariant method available to supply a note or description for the variant. These descriptions will be printed by the outgoingVariants report and defaults have been added for existing secondary variants produced by the Java plugin.

Resolvable Configurations

There is a new resolvableConfigurations report available which will display information about all the configurations in a project that can be resolved.

This report compliments the outgoingVariants report and is meant to be run from the consumer side of a dependency to determine why a particular variant of a producer project was selected by this consumer project when the consumer depends upon the producer. It includes the following information:

See the ResolvableConfigurations DSL reference for more details.

Dependency Insights

The dependencyInsight report provides information about a specific dependency, including what variant was selected, and the attributes used during resolution.

The report now uses a table to display variants, which makes it easier to tell where attribute values are from, and see why a particular variant was selected:

dependencyInsight output

  1. The variant name is listed at the top, after the word "Variant"
  2. The variant output is now in table format.
  3. Attributes only present in the variant's metadata only contain text in the "Provided" column
  4. Attributes present in both the variant's metadata and requested by the configuration contain text in both columns
  5. Attributes only requested by the configuration only contain text in the "Requested" column

As seen in (3) and (5), items are colored orange if they are not present in one column. The table is sorted first by groups (3), (4), and (5); then alphabetically inside each group.

Dependency resolution results can be used as task inputs

Tasks may need to access dependency resolution results. For example, built-in tasks like dependencies and dependencyInsight do so in order to provide reporting about resolved artifacts and dependency graphs. Other tasks may produce file outputs based on dependency resolution results. Previously, it was only possible by performing dependency resolution in a task action. However, this resulted in suboptimal performance.

Starting with Gradle 7.5 it is now possible to declare dependency resolution results as task inputs.

This allows writing tasks which consume dependency resolution results. Declaring such inputs instead of doing undeclared dependency resolution in task actions allows Gradle to optimise for build incrementality. Additionally, these new types of task inputs are fully supported by the configuration cache.

You can learn more in the Authoring Tasks user manual chapter and with the dedicated sample.

Configuration cache improvements

The configuration cache improves build time by caching the result of the configuration phase and reusing this for subsequent builds.

Running external processes at configuration time

Previously, external processes started with exec or javaexec APIs were ignored by configuration cache, and it could be a potential correctness issue if the output of the external process affects the configuration.

A new Provider-based API is now available to obtain the output of the external process in the configuration-cache-compatible way. The exec and javaexec APIs are now disallowed if the configuration cache is enabled in order to prevent potential issues.

If a more complex interaction with the external process is necessary, then a custom ValueSource implementation can be used. The injected ExecOperations service should be used to run the external process.

Files read at configuration time become build configuration inputs

Files read at configuration time with FileInputStream or some Kotlin APIs now automatically become build configuration inputs. The configuration cache is invalidated if the contents of such file(s) change between builds.

Previously, file reads were ignored, and it could be a potential correctness issue if the contents of the file(s) affected the configuration.

New ways to access environment without unnecessary invalidations of the configuration cache

Since the automatic build configuration inputs detection was introduced in Gradle 7.4, some common patterns of reading subsets of environment variables or system properties were causing excessive invalidations of the configuration cache, leading to suboptimal performance. For example, iterating over all environment variables to find the ones with names starting with some prefix caused all available variables, even the unrelated ones, to become configuration inputs.

Two new options are now available to mitigate that. For simpler use cases, there are the Provider-based APIs to access system properties or environment variables with names starting with some prefix. Advanced processing, like filtering names with regular expression, can be done inside a custom ValueSource implementation. Reading a file, an environment variable, or a system property no longer adds a build configuration input inside the implementation of the ValueSource. The value of the ValueSource is recomputed each time the build runs, and the configuration cache entry is only invalidated if the value changes.

New compatible plugins and tasks

The kotlin-dsl plugin is now compatible with the configuration cache.

The dependencyInsight, outgoingVariants and resolvableConfigurations tasks are now compatible with the configuration cache.

New STABLE_CONFIGURATION_CACHE feature flag

Configuration caching introduces a number of requirements regarding the build logic. Many problems are already reported in the HTML report. At the moment, adjusting the build logic to be fully compatible with configuration cache can be a significant effort for complex builds.

This release introduces the STABLE_CONFIGURATION_CACHE flag allowing gradual rollout of the most potentially disruptive requirements. This flag currently enables validations like detecting undeclared shared build service usage and external processes used at configuration time.

It is recommended to enable this flag as soon as possible in order to be ready for when the flag is removed and make the linked features enabled by default.

Learn more about what this feature flag enables in the user manual.

JVM toolchains improvements

Java toolchains provide an easy way to declare which Java version your project should be built with. By default, Gradle will detect installed JDKs or automatically download new toolchain versions.

Java toolchains can download any JDK by automatically selecting between Adoptium and AdoptOpenJDK

Gradle now checks the Adoptium API first when downloading JDKs, rather than only using the legacy AdoptOpenJDK API. This allows downloading the new JDK 18 releases, which are not available via AdoptOpenJDK, while still maintaining the ability to download versions that are no longer supported by Adoptium, such as JDK 9-10 and 12-16.

In case you are using an internal mirror to download JDKs, there is a new Gradle property org.gradle.jvm.toolchain.install.adoptium.baseUri to control the Adoptium base URI. This is in addition to theorg.gradle.jvm.toolchain.install.adoptopenjdk.baseUri property, which is still used if a JDK is not found in the Adoptium API.

IDE integration improvements

Improved test sources separation in Eclipse

This release provides improved support for test sources in Eclipse.

The Eclipse classpath file generated by the eclipse plugin has the following changes:

eclipse {
    classpath {
        testSourceSets = [sourcesSets.test, sourceSets.myTestSourceSet]
        testConfigurations = [configuration.myTestConfiguration]
    }
}

These changes are reflected also when the project is synchronized in Buildship.

See the documentation for more details.

Query a single property with the properties task

The built-in properties task prints all project properties to the console. Now, the task takes an optional --property argument which configures it to display the selected property only.

$ gradle properties --property buildFile

> Task :properties

------------------------------------------------------------
Root project 'example-project'
------------------------------------------------------------

buildFile: /path/to/project/build.gradle

BUILD SUCCESSFUL in 550ms
1 actionable task: 1 executed

This is useful for keeping track of specific properties on CI systems, and requires much less parsing and filtering than before.

Groovydoc exposes more options

The Groovydoc task now exposes more options:

These defaults are the same as what was previously used, so there should be no changes to the default behavior.

--show-version (-V) flag

The -V flag (long form --show-version) instructs Gradle to first print version information and then continue executing any requested tasks. This is in contrast to the pre-existing -v (long form --version) flag which prints version information and then immediately exits.

This flag may be useful in CI environments to record Gradle version information in the log as part of a single Gradle execution.

Performance Improvements

Checkstyle tasks use toolchains and execute in parallel by default

The Checkstyle plugin now uses the Gradle worker API to run Checkstyle as an external worker process, so that multiple Checkstyle tasks may now run in parallel within a project. This can greatly increase overall build performance when several of these tasks exist within a single project. The memory used by the process is controlled via the minHeapSize and maxHeapSize properties.

Checkstyle now uses JVM toolchains in order to minimize JDK installation requirements. In Java projects, Checkstyle will use the same version of Java required by the project. In other types of projects, Checkstyle will use the version of Java that is used by the Gradle daemon.

Run a single PMD task on multiple threads

PMD is a quality analysis tool that runs on the Java source files of your project.

With this version of Gradle, the thread parameter PMD offers is now exposed through the PMD extension and tasks. This allows configuration of PMD to run its analysis on more than one thread.

See the documentation for more information.

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.

Fixed issues

mustRunAfter constraint is violated by finalizedBy dependency

In previous Gradle versions, mustRunAfter constraints between regular tasks and finalizer task dependencies would not be honored.

For a concrete example, consider the following task graph definition:

          tasks {
                register("dockerTest") {
                    dependsOn("dockerUp")     // dependsOn createContainer mustRunAfter removeContainer
                    finalizedBy("dockerStop") // dependsOn removeContainer
                }

                register("dockerUp") {
                    dependsOn("createContainer")
                }

                register("dockerStop") {
                    dependsOn("removeContainer")
                }

                register("createContainer") {
                    mustRunAfter("removeContainer")
                }

                register("removeContainer") {
                }
            }

The relevant constraints are:

Prior to Gradle 7.5, gradle dockerTest would yield the following order of execution, in violation of the mustRunAfter constraint between :createContainer and :removeContainer:

> Task :createContainer UP-TO-DATE
> Task :dockerUp UP-TO-DATE
> Task :dockerTest UP-TO-DATE
> Task :removeContainer UP-TO-DATE
> Task :dockerStop UP-TO-DATE

Starting with Gradle 7.5, mustRunAfter constraints are fully honored yielding the following order of execution:

> Task :removeContainer UP-TO-DATE
> Task :createContainer UP-TO-DATE
> Task :dockerUp UP-TO-DATE
> Task :dockerTest UP-TO-DATE
> Task :dockerStop UP-TO-DATE

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.