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.
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.
Gradle's toolchain support allows provisioning and selection of JDK versions required for building projects (compiling code, running tests, etc) and running Gradle itself.
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:
IntelliJ IDEA support is available starting from version 2025.1 EAP or later and includes the configurable values in the Settings menu:
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.
scala
extensionThe 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.
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.
Gradle provides rich APIs for plugin authors and build engineers to develop custom build logic.
ProjectLayout
API improvementThe 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.
artifactTransforms
report taskArtifact 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.
The report includes the following details:
For more information, refer to the ArtifactTransformsReportTask DSL reference.
TestEventReporting
API improvementsGradle 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.
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()));
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.
distribution-base
plugin for custom distributionsThe 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.
dependencies
block APIThe 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.
Retrieving the fixed issue information for 8.13 …
Known 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 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.