Gradle 7.6.4 Release Notes

# Gradle Release Notes

### Version 7.6.4

The Gradle team is excited to announce Gradle 7.6.4.

This is the fourth patch release for Gradle 7.6.

This release addresses security vulnerabilities:

- Apache Ant insecure temporary file vulnerability
- Guava insecure temporary directory
- Ivy Improper Restriction of XML External Entity Reference and related Gradle issue #24795

It also fixes the following issues related to multi-release JARs:

- #27156 Gradle 7.6.3 fails with plugins that use multi-release JAR files
- #27856 Gradle 7.6.3 fails to incrementally compile when the classpath contains a multi-release jar with a Java 21 class

and contains version updates for Jackson and Maven dependencies.

Issues fixed in the third patch release:

- Security vulnerability: Incorrect permission assignment for symlinked files used in copy or archiving operations
- Security vulnerability: Possible local text file exfiltration by XML External entity injection
- #25781 Backport finalized task performance fix to 7.6.x
- #25802 Backport cgroups fix to 7.6.x

Issues fixed in the second patch release:

- Security vulnerability: Dependency cache path traversal
- Security vulnerability: Path traversal vulnerabilities in handling of Tar archives
- #23201 Backport dependency upgrades to 7.x
- #23202 Backport Scala incremental compilation fixes
- #23325 Backport JSoup update to resolve CVE-2022-36033
- #23458 Backport JUnit5 dynamic test logging bug fix
- #23681 Dependency graph resolution: Equivalent excludes can cause un-necessary graph mutations [backport 7.x]
- #23922 Backport "Use Compiler API data for incremental compilation after a failure" to 7.x
- #23951 Exclude rule merging: missing optimization [Backport 7.x]
- #24132 Extending an already resolved configuration no longer works correctly [backport 7.x]
- #24234 7.6.1 breaks gradle-consistent-versions
- #24390 Gradle 7.4 fails on multi release jar's with JDK 19 code
- #24439 Gradle complains about invalid tool chain - picking up the source package location - it should just ignore them [Backport]
- #24443 Maven artifact referenced only in dependency constraints raises IllegalStateException: Corrupt serialized resolution result [backport]
- #24901 Backport fix for test exception that cannot be deserialized to 7.x

Issues fixed in the first patch release:

- #19065 Platform dependencies not possible in dependency block of test suite plugin
- #22688 Increased memory usage (with -p option)
- #22796 Building gradle itself fails during toolchain download: permission denied copying a file within `.gradle/jdks`
- #22875 Regression with 7.6: @pom artifact in JVM library project is no longer found
- #22937 Remove safe credentials reference
- #22973 Kotlin MPP plugin broken with Gradle 7.6 due to signature change in TestResultProcessor
- #23016 toolchainManagement.jvm.javaRepositories should not expose the full surface of NamedDomainObjectList
- #23025 Back-port toolchain related fixes to 7.6.1
- #23053 Auto-provisioning/auto-detection of IBM Semeru toolchains is broken with Gradle 7.6
- #23074 Docs: Build Lifecycle starts halfway through a point
- #23096 Classifiers of version catalog are discarded while copied to anothor dependency
- #23111 Ant closures are broken with Gradle 7.6
- #23178 Mention the Foojay Toolchain Resolver plugin in the Gradle manual
- #23215 Gradle 7.6: high memory usage (android project)
- #23224 Backport to 7.6.1 "Fix for Incremental compilation with modules"
- #23294 "Unable to make progress running work" together with --continue and failing tasks (Backport to 7.6.1)
- #23555 Improve Toolchain related deprecation nagging in 7.6
- #23894 Update EOL policy
- #23910 Backport trusting only full GPG keys in dependency verification [Backport 7.6.1]
- #23941 Typo in v7.6 docs about disabling_the_daemon
- #23985 Resolving of manually created configuration creates a ResolveException

We recommend users upgrade to 7.6.4 instead of 7.6.

This release includes building and running code with Java 19, a flag to rerun tasks individually, a new strongly-typed dependencies block for JVM test suites, and a pluggable system for Java Toolchains provisioning.

As always there are also performance improvements like enhancements to the configuration cache and incremental compilation.

We would like to thank the following community members for their contributions to this release of Gradle: altrisi, aSemy, Ashwin Pankaj, Aurimas, BJ Hargrave, Björn Kautler, Bradley Turek, Craig Andrews, Daniel Lin, David Morris, Edmund Mok, Frosty-J, Gabriel Feo, Ivan Gavrilovic, Jendrik Johannes, John, Joseph Woolf, Karl-Michael Schindler, Konstantin Gribov, Leonardo Brondani Schenkel, Martin d'Anjou, Michael Bailey, Pete Bentley, Rob Bavey, Sam Snyder, sll552, teawithbrownsugar, Thomas Broadley, urdak, Varun Sharma, Xin Wang

## Table Of Contents

## Upgrade instructions

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

`./gradlew wrapper --gradle-version=7.6.4`

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

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

## New features and usability improvements

### JVM

#### Added Support for Java 19

Gradle 7.6 supports compiling, testing and running on Java 19.

#### Introduced strongly-typed `dependencies` block for JVM test suites

The JVM test suite `dependencies` block now uses a strongly-typed API. This makes the build logic cleaner and improves assistance in the IDEs, especially with the Kotlin DSL.

Previously, the JVM test suite `dependencies` block only accepted dependencies of type `Object`.

    testing {
        suites {
            val test by getting(JvmTestSuite::class) {
                useJUnitJupiter()
                dependencies {
                    implementation(project(":foo")) {
                        // Receiver (this) is of type Dependency
                        // To access ProjectDependency
                        // methods, smart-cast:
                        this as ProjectDependency
                        // Now available as a ProjectDependency
                        println(dependencyProject)
                    }
                }
            }
        }
    }

Now, each notation provides its `Dependency` subtype:

    testing {
        suites {
            val test by getting(JvmTestSuite::class) {
                useJUnitJupiter()
                dependencies {
                    implementation(project(":foo")) {
                        // `this` already of type ProjectDependency
                        println(dependencyProject)
                    }
                }
            }
        }
    }

For example, using a `String` provides an `ExternalModuleDependency`. Using a `FileCollection` provides a `FileCollectionDependency`. This allows Java and Kotlin to properly configure all types of dependencies and improves IDE support for the Groovy DSL.

In addition, the Kotlin DSL now supports named arguments for external dependencies in this block:

    testing {
        suites {
            "test"(JvmTestSuite::class) {
                useJUnitJupiter()
                dependencies {
                    implementation(module(group = "com.google.guava",
                                   name = "guava",
                                   version = "32.1.3-jre"))
                }
            }
        }
    }

For more information about the test suite `dependencies` block, see Differences Between Test Suite and Top-Level Dependencies.

#### Added support for Java Toolchain downloads from arbitrary repositories

Starting in Gradle 7.6, Gradle can download JVM toolchains from arbitrary repositories. By default, Gradle downloads toolchains from Adoptium/AdoptOpenJDK. You can now override the default providers with repositories of your choice using a toolchain resolver plugin.

For example, the following uses custom plugins that provide `AzulResolver` and `AdoptiumResolver` to add custom toolchains for Adoptium and Azul:

    toolchainManagement {
        jvm {
            javaRepositories {
                repository("azul") {
                    resolverClass.set(AzulResolver::class.java)
                    credentials {
                        username = "user"
                        password = "password"
                    }
                    authentication {
                        create<DigestAuthentication>("digest")
                    }
                }
                repository("adoptium") {
                    resolverClass.set(AdoptiumResolver::class.java)
                }
            }
        }
    }

For more information about using custom toolchain resolvers, see the Toolchain Download Repositories documentation. For more information about writing custom toolchain resolvers, see the Toolchain Resolver Plugins documentation.

#### Added support for incremental compilation following a compilation failure

Gradle supports Java incremental compilation by default and Groovy incremental compilation as an opt-in experimental feature.

In previous versions, a compilation failure caused the next compilation to perform a full recompile. Starting in Gradle 7.6, Java and Groovy incremental compilation can work even after a failure.

This feature is enabled by default when incremental compilation is enabled. The feature can be disabled with the `incrementalAfterFailure` compile option.

#### Introduced support for Java 9+ network debugging

You can run a Java test or application child process with debugging options to accept debugger client connections over the network. If the debugging options only specify a port, but not a host address, the set of accepted connections depends on your version of Java:

- Before Java 9, the debugger client accepts connections from any machine.
- Starting in Java 9, the debugger client accepts connections originating from the host machine only.

This release adds a new property to `JavaDebugOptions`: `host`. This allows you to specify the debugger host address along with the port.

Similarly, the new Gradle property `org.gradle.debug.host` now enables running the Gradle process with the debugger server accepting connections via network on Java 9 and above.

On Java 9 and above, use the special host address value `*` to make the debugger server listen on all network interfaces. Otherwise, use the address of one of the machine's network interfaces.

#### Revised dependencies generated from `init` Maven conversions from `implementation` to `api`

The `init` task now adds compile-time Maven dependencies to Gradle's `api` configuration when converting a Maven project. This sharply reduces the number of compilation errors. It is still recommended to use `implementation` where possible.

For more information about Maven conversions, see the Build Init Plugin.

### General Improvements

#### Introduced flag for individual task `rerun`

All tasks can now use the `--rerun` option. This option works like `--rerun-tasks`, except `--rerun` only affects a single task. For example, you can force tests to ignore up-to-date checks like this:

    gradle test --rerun

For more information about the rerun option, see Built-in Task Options.

#### Relocated convention plugins in projects generated with `init`

> 🐣 This feature is incubating.

When generating builds with the `init` task and opting in to incubating features, Gradle now places convention plugins under the `build-logic` directory instead of in `buildSrc`.

Convention plugins are Gradle’s recommended way of organizing build logic where you can compose custom build logic by applying and configuring both core and external plugins.

For more information about convention plugins, see Convention Plugins.

#### Introduced network timeout configuration for wrapper download

It is now possible to configure the network timeout for downloading Gradle wrapper files. The default value is 10000ms and can be changed in several ways:

From the command line:

    $ ./gradlew wrapper --network-timeout=30000

In your build scripts or convention plugins:

    tasks.wrapper {
        networkTimeout.set(30000)
    }

Or in `gradle/wrapper/gradle-wrapper.properties`:

    networkTimeout=30000

For more information about the Gradle wrapper, see Gradle Wrapper.

#### Introduced ability to explain why a task was skipped with a message

You can now provide a reason message when conditionally disabling a task using the `Task.onlyIf` predicate:

    tasks.register("slowBenchmark") {
        onlyIf("slow benchmarks not enabled") {
            false
        }
    }

Gradle outputs reason messages at log level `INFO`. To output reason messages to the console, use the `--info` or `--debug` log levels.

### Dependency Management

#### Clarified the ordering of disambiguation rule checks in `resolvableConfigurations` reports

Attribute disambiguation rules control the variant of a dependency selected by Gradle when:

- multiple variants of a dependency exist with different compatible values for a requested attribute
- no variant exactly matches that attribute

Attribute disambiguation rules select a single matching dependency variant in such cases. The `resolvableConfigurations` reporting task now prints the order of these rules:

    $ ./gradlew resolvableConfigurations

    --------------------------------------------------
    Disambiguation Rules
    --------------------------------------------------
    The following Attributes have disambiguation rules defined.

        - flavor
        - org.gradle.category (1)
        - org.gradle.dependency.bundling (5)
        - org.gradle.jvm.environment (6)
        - org.gradle.jvm.version (3)
        - org.gradle.libraryelements (4)
        - org.gradle.plugin.api-version
        - org.gradle.usage (2)

    (#): Attribute disambiguation precedence

For more information, see Attribute Disambiguation Rules.

### Configuration Cache

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

#### Improved configuration cache failure recovery

In previous Gradle versions, it was possible to leave a configuration cache entry in a permanently broken state after a dependency resolution failure. Following builds would simply reproduce the failure without any attempt to recover from it.

Starting with Gradle 7.6, this is no longer the case. Gradle recovers from dependency resolution failures in exactly the same way whether the configuration cache is enabled or not.

#### Extended configuration cache task compatibility

The `dependencies`, `buildEnvironment`, `projects` and `properties` tasks are now compatible with the configuration cache.

#### Added configuration cache support to the Maven Publish Plugin

The Maven Publish Plugin is now compatible with the configuration cache.

Note that when using credentials, the configuration cache requires safe credential containers.

#### Improved handling of `--offline` option

Gradle now stores configuration caches for online and offline modes separately. This change supports builds and plugins that need to behave differently during configuration depending on whether the `--offline` option is in effect.

For more information, see the `--offline` CLI option.

### Plugin Development

#### Introduced support for task options of type `Integer`

You can now pass integer task options declared as `Property<Integer>` from the command line.

For example, the following task option:

    @Option(option = "integer-option", description = "description")
    public abstract Property<Integer> getIntegerOption();

can be passed from the command line as follows:

    gradle myCustomTask --integer-option=123

### IDE Integration

These improvements are for IDE integrators and are not directly for end-users until their specific IDE implements the integration.

#### Enhanced test events to distinguish between assertion and framework failures

Gradle 7.6 introduces new failure types for the `Failure` interface returned by `FailureResult.getFailures()`: `TestAssertionFailure` and `TestFrameworkFailure`. IDEs can now distinguish between assertion and framework failures using progress event listeners. For test frameworks that expose expected and actual values, `TestAssertionFailure` contains those values.

#### Introduced `TestLauncher` task execution

The `TestLauncher` interface now allows Tooling API clients to execute any tasks along with the selected tests:

    ProjectConnection connection = ...
    connection.newTestLauncher()
              .withTaskAndTestClasses("integTest", ["org.MyTest"])
              .forTasks("startDB")
              .run()

#### Introduced class, method, package, and pattern test selection via `TestLauncher`

The TestLauncher interface now allows Tooling API clients to select test classes, methods, packages and patterns with a new API.

    TestLauncher testLauncher = projectConnection.newTestLauncher();
    testLauncher.withTestsFor(spec -> {
        spec.forTaskPath(":test")
            .includePackage("org.pkg")
            .includeClass("com.TestClass")
            .includeMethod("com.TestClass")
            .includePattern("io.*")
    }).run();

#### Added support for passing system properties to the build with the Tooling API

Before 7.6, the Tooling API started builds with the system properties from the host JVM. This leaked configuration from the IDE to the build. Starting in Gradle 7.6, `LongRunningOperation.withSystemProperties(Map)` provides an isolated set of build system properties. For more information, see `LongRunningOperation`.

## Promoted features

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.

This Gradle release promotes the following features to stable:

- `getTestSources` and `getTestResources`
- `getDestinationDirectory` and `getTestResults`

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