Gradle Release Notes

We are excited to announce Gradle 8.13 (released 2025-02-26).

This release introduces Daemon JVM auto-provisioning, which automatically downloads the JVM required by the Gradle Daemon to run.

Gradle 8.13 also adds explicit Scala version configuration and JUnit XML timestamps with millisecond precision.

For build authors and plugin developers, this release adds improved access to the settings directory in build scripts, a new artifact transform report, custom test report generation, and the new distribution-base plugin.

We would like to thank the following community members for their contributions to this release of Gradle: Adam, Adam, Ahmad Al-Masry, Ahmed Ehab, Aurimas, Baptiste Decroix, Björn Kautler, Borewit, Jorge Matamoros, Lei Zhu, Madalin Valceleanu, Mohammed Thavaf, Patrick Brückner, Philip Wedemann, Roberto Perez Alcolea, Róbert Papp, Semyon Gaschenko, Shi Chen, Stefan M., Steven Schoen, tg-freigmbh, TheGoesen, Tony Robalik, Zongle Wang.

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 8.13 by updating the wrapper in your project:

./gradlew wrapper --gradle-version=8.13 && ./gradlew wrapper

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

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

New features and usability improvements

Toolchain support

Gradle's toolchain support allows provisioning and selection of JDK versions required for building projects (compiling code, running tests, etc) and running Gradle itself.

Daemon toolchain auto-provisioning

Since Gradle 8.8, users can specify a different JVM for building their project than the one used to run Gradle by configuring the Daemon JVM criteria.
Gradle first attempts to locate a compatible Java toolchain from installed versions—this process is known as Daemon JVM auto-detection.

With the introduction of Daemon JVM auto-provisioning, Gradle can now also download a matching Java toolchain when none is found locally.

Running the updateDaemonJvm task generates the gradle/gradle-daemon-jvm.properties file, which now includes download URLs for the required JDKs:

toolchainUrl.LINUX.AARCH64=https\://server.com/jdk
toolchainUrl.LINUX.X86_64=https\://server.com/jdk
...
toolchainVendor=adoptium
toolchainVersion=17

If no installed JDK matches the specified version or vendor, Gradle automatically downloads the required version:

Daemon JVM Criteria Console Example

IntelliJ IDEA support is available starting from version 2025.1 EAP or later and includes the configurable values in the Settings menu:

Daemon JVM Criteria IDE Example

To enable auto-provisioning, the latest version of the foojay plugin (or a custom implementation) is required:

plugins {
    // Apply the foojay-resolver plugin to allow automatic download of JDKs
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
}

Once the plugin is applied, running the updateDaemonJvm task:

./gradlew updateDaemonJvm --jvm-version=17 --jvm-vendor=adoptium

Populates gradle/gradle-daemon-jvm.properties with the JDK download information:

toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ff8d269e2495c538cfa04b4b52d22286/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4dfe7aab2abf71db71537e9dca36c154/redirect
...
toolchainVendor=adoptium
toolchainVersion=17

The resolved platforms and URLs are customizable. For more details, see the Daemon JVM criteria documentation.

Explicit Scala version declaration in the scala extension

The Scala plugin provides support for compiling, testing, and packaging Scala projects.

Starting in this version of Gradle, when applying the scala-base or scala plugins, you can now explicitly declare the Scala version on the scala extension. This allows Gradle to automatically resolve the required Scala toolchain dependencies, eliminating the need for the user to declare them manually. It also removes the need to infer the Scala version from the production runtime classpath, which was error-prone.

Now, you can explicitly set the Scala version in the scala extension, and the scala-library dependency is no longer required:

plugins {
    id("scala")
}

repositories {
    mavenCentral()
}

scala {
    scalaVersion = "2.13.12"
    // OR 
    scalaVersion = "3.6.3"
}

Previously, you had to declare a scala-library dependency, like this:

plugins {
    id("scala")
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.scala-lang:scala-library:2.13.12")
    // OR
    implementation("org.scala-lang:scala3-library_3:3.6.3")
}

For more details on using the Scala plugin, see the documentation.

Additional precision in JUnit XML timestamps

Gradle provides built-in support for running JUnit tests and generating detailed reports. The JUnit XML report generated by the test task now includes millisecond precision in test event timestamps:

<testsuite name="ExampleTest" tests="1" failures="0" errors="0" timestamp="2024-02-03T12:34:56.789" time="1.234">
    <testcase name="testExample" classname="com.example.ExampleTest" time="1.234">
    </testcase>
</testsuite>

This change improves accuracy when analyzing test execution times, particularly in environments where precise timing is critical.

For more details on JUnit test reporting in Gradle, see Testing in JVM Projects.

Build authoring improvements

Gradle provides rich APIs for plugin authors and build engineers to develop custom build logic.

ProjectLayout API improvement

The ProjectLayout class provides access to directories and files within a project. Starting with this version of Gradle, it can also access the settings directory (the location of the settings.gradle(.kts) file).

While the settings directory is not specific to any project, some use cases require resolving file paths relative to it:

val versionFile = layout.settingsDirectory.file("version.txt")

Previously, accessing the settings directory required using rootProject.layout.projectDirectory. This approach involved accessing the rootProject object, which is discouraged, and then manually resolving paths to the settings directory:

val versionFile = rootProject.layout.projectDirectory.file("version.text")

The new capability addresses a common scenario: resolving files shared across all projects in a build, such as linting configurations or version.txt files in the root folder.

Refer to ProjectLayout.getSettingsDirectory() for additional details.

New artifactTransforms report task

Artifact Transforms modify or transform the artifacts of dependencies during the dependency resolution process.

A new artifactTransforms task is available, providing information about all the registered Artifact Transforms in a project.

The report produced by the task helps build authors identify the transforms registered by build scripts and plugins in their projects. Viewing the list of registered transforms is particularly useful for debugging ambiguous transform failures.

Artifact Transforms Report Example

The report includes the following details:

For more information, refer to the ArtifactTransformsReportTask DSL reference.

TestEventReporting API improvements

Gradle provides an HTML test report to help you understand and resolve test failures. This report is automatically generated when using the test task with supported test frameworks, such as JUnit.

Plugin authors and platform providers can now leverage the Test Event Reporting APIs to capture test events and generate reports for tests executed outside Gradle's built-in testing infrastructure:

public abstract class CustomTest extends DefaultTask {

    @Inject
    protected abstract ProjectLayout getLayout();
    
    @Inject
    protected abstract TestEventReporterFactory getTestEventReporterFactory();

    @TaskAction
    void runTests() {
        try (TestEventReporter test = getTestEventReporterFactory().createTestEventReporter(
                "custom-test",
                getLayout().getBuildDirectory().dir("test-results/custom-test").get(),
                getLayout().getBuildDirectory().dir("reports/tests/custom-test").get()
        )) {
            // Start the test
            test.started(Instant.now());

            // Execute custom test...
            
            // Report test outcome
            if (testFailureCount > 0) {
                test.failed(Instant.now());
            } else {
                test.succeeded(Instant.now());
            }
        }
    }
}

This integration allows custom test frameworks to generate rich HTML test reports consistent with Gradle's built-in reporting format, enhancing visibility and usability.

You can find additional details and sample code in Test Reporting API.

The following sections highlight two key features of this API.

Metadata support

Custom tests can include metadata to provide supplementary information about test execution.

The metadata is displayed in the HTML test report for better visibility:

test.metadata(Instant.now(),"Parent class:", String.valueOf(result.getTestIdentifier().getParentId().get()));

Test API Metadata Example

Nesting support

Hierarchical nesting is supported to logically group test suites and individual tests. This ensures detailed and structured reporting, with rich metadata scoped to each level:

try (GroupTestEventReporter outer = root.reportTestGroup("OuterNestingSuite")) {
    outer.started(Instant.now());
        try (GroupTestEventReporter inner = root.reportTestGroup("InnerNestingSuite")) {
            inner.started(Instant.now());
            try (TestEventReporter test = inner.reportTest("nestedTest", "nestedTest()")) {
                test.started(Instant.now());
                test.succeeded(Instant.now());
            }
            inner.succeeded(Instant.now());
    }
    outer.succeeded(Instant.now());
}

Nested events are reflected in the HTML test reports, providing clear traceability.

New distribution-base plugin for custom distributions

The Distribution Plugin simplifies the packaging and distribution of project binaries, scripts, and other resources. It creates a distributable archive (ZIP or TAR) containing specified project outputs and provides tasks for assembling and installing the distribution.

Gradle now includes a distribution-base plugin, which mirrors the functionality of the Distribution Plugin but does not add a default distribution. Instead, the existing distribution plugin acts as a wrapper for the distribution-base plugin, adding a default main distribution.

The distribution-base plugin is particularly useful for plugin developers who want the capabilities of the Distribution Plugin without a main distribution:

plugins {
    id("distribution-base")
}

distributions {
    create("custom") {
        distributionBaseName = "customName"
        contents {
            from("src/customLocation")
        }
    }
}

For more details, see the Distribution Plugin documentation.

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.

The Tooling API is an interface that allows external tools, such as IDEs, to interact with and control Gradle builds.

The API to asynchronously send data to the client, which includes the BuildActionExecuter.setStreamedValueListener(StreamedValueListener) method, the StreamedValueListener type, and the BuildController.send(Object) method has been promoted to stable.

Strongly-typed dependencies block API

The strongly-typed dependencies block API introduced in Gradle 7.6 is now partially stable. Version catalog dependencies remain under review for potential changes.

The Dependencies API enables plugin authors to create custom DSL-like dependencies blocks, similar to the top-level dependencies block in a build script.

Fixed issues

Retrieving the fixed issue information for 8.13 …

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.