Gradle Release Notes

Version 3.5.1

The Gradle team is pleased to announce Gradle 3.5.

First and foremost, we're excited to announce the new Build Cache! Beyond incremental builds, Gradle can save time by reusing outputs from previous executions of a task, resolving them locally or remotely. We’ve worked hard to ensure many built-in tasks are cacheable and safe to try; however, this feature should not be used in production without fully understanding its current limitations, so it is not enabled by default.

We have been testing this feature at scale for quite some time on the Gradle build itself and with enterprise partners, and the feedback has been very positive. While this feature is incubating, we are improving the user experience, documentation, and debuggability so that everyone can enable the Build Cache eventually.

We would like your feedback. Please read the Build Cache user manual, try it in non-critical environments, and submit GitHub issues with build scans if you encounter problems.

Next, we lamented that sometimes Gradle console output did not show all work-in-progress during a build (especially with --parallel), so we’ve developed brand new console output!

3.5 Console

Gradle Script Kotlin v0.8.0 (included in the distribution) is a major step forward in usability. It brings a more consistent DSL, convenient and type-safe access to contributed project extensions and conventions, much better error reporting, bug fixes and, of course, the latest and greatest Kotlin release.

Finally, plugin resolution rules give you tighter control over how plugins are resolved through the new pluginManagement {} block.

We hope you will build happiness with Gradle 3.5, and we look forward to your feedback via Twitter or on GitHub.

Table Of Contents

New and noteworthy

Here are the new features introduced in this Gradle release.

Console upgrade

When attached to a terminal, Gradle will now show you a build summary and more detailed work-in-progress. The build summary tells you how much of the task graph has been completed. The work-in-progress section tells you which tasks are being processed. It gets much more interesting when you turn on --parallel.

If you encounter any problems, use the --console plain option and please file an issue with your environment and terminal information.

Faster builds with the Gradle Build Cache

This release adds the Gradle build cache that speeds up builds by reusing outputs produced by other builds. The build cache works by storing (locally or remotely) build outputs and allowing builds to fetch these outputs from the cache when it is determined that inputs have not changed, avoiding the expensive work of regenerating them.

A first feature using the build cache is task output caching. Task output caching leverages the same intelligence as up-to-date checks that Gradle uses to avoid work when a previous local build has already produced a set of task outputs. But instead of being limited to the previous build in the same workspace, task output caching allows Gradle to reuse task outputs from any earlier build in any location on the local machine. When using a shared build cache for task output caching this even works across developer machines and build agents.

After upgrading to 3.5, try out the Gradle Build Cache straightaway on a project that uses the Java plugin by running:

gradle --build-cache clean assemble
gradle --build-cache clean assemble

Your second build should be faster because some task outputs, like Java classes, can be reused from the first build. These outputs are pulled from the Gradle build cache.

In this simple example it was the same build in the same workspace which produced the outputs, but these could have also been produced by an earlier build in a different workspace, when having worked on the same branch earlier while switching branches in between or even by another developer or build agent.

Without any extra configuration, your build will use a local directory in your GRADLE_USER_HOME to store task outputs. To take this to another level, you can configure your build to pull task outputs from a build cache shared with your team. You can configure nginx to act as a shared build cache. A scalable, highly-available build cache backend is coming soon in Gradle Enterprise.

We provide a recommended configuration that uses your continuous integration builds to populate a shared build cache and allows all developers to pull from that build cache. Our recommended configuration does not directly share task outputs among developer builds.

Task output caching is an opt-in feature for tasks, so not every task will be cacheable yet. For example, tasks from the Gradle Android and Kotlin plugins are not cacheable yet. Further, some tasks like a simple Copy task are not and should not be cached. Look at the build cache user guide chapter to see all of the current limitations with using the build cache.

Plugin resolution rules

Gradle now allows you to adjust how plugins are resolved by providing plugin resolution rules. For instance, you could specify a default version for a plugin so you don't have to repeat it in every project. Or you could tell Gradle what implementation artifact it should look for in case the plugin is not published with plugin markers.

pluginManagement {
    repositories {
        maven { url = 'someUrl'}
    resolutionStrategy {
        eachPlugin {
            if ( = 'my.plugins') {

The pluginManagement block supersedes the existing pluginRepositories block. Moreover, you now have full access to the Settings DSL inside that block, so you can make decisions e.g. based on start parameters. You can also configure plugin management from an init script by using the settingsEvaluated {} hook.

Kotlin Build Scripts

Gradle Script Kotlin v0.8.0, included in Gradle 3.5, greatly improves the user experience and parity with Groovy build scripts.

Updates since v0.5.1:

... and a lot more. Full details are available in the Gradle Script Kotlin v0.6.0, v0.7.0 and v0.8.0 release notes.

More work avoidance when using @Classpath task properties

For built-in and custom tasks that use the @Classpath annotation, Gradle now performs deeper inspection of the classpath to filter out some differences that do not affect task execution. Gradle will ignore changes to timestamps within a jar file and the order of entries inside a jar file.

In previous versions, for tasks like Javadoc, Checkstyle and Test, Gradle would consider the task out-of-date if the content of the classpath changed in any way (order of classes in a jar, timestamps of class files, etc).

Extensions now have a public type

Extensions can now be registered in ExtensionContainers with an explicit public type. This allows plugin authors to hide their implementation type from build scripts and allow ExtensionContainers to expose a schema of all the registered extensions.

For example, if you have a FancyExtension type, implemented by some DefaultFancyExtension type, here is how you should register it:

// If you want to delegate the extension instance creation to Gradle:
project.extensions.create FancyExtension, 'fancy', DefaultFancyExtension

// Or if you need to create the extension instance yourself:
FancyExtension fancyInstance = new DefaultFancyExtension(...)
project.extensions.add FancyExtension, 'fancy', fancyInstance

Tooling API improvements

BuildActionExecutor supports running tasks

Tooling API clients like IDEs can now run tasks before running a build action. This allows them to fetch tooling models which depend on the result of executing some task. This mirrors the existing ModelBuilder.forTasks() API.

Specify environment variables

Tooling API clients can now specify environment variables to use when invoking a Gradle build.

Progress events for Gradle distribution download

The Tooling API can now report progress when it downloads of the Gradle distribution. A new type of ProgressEvent, called StatusEvent, is passed to the ProgressListener.statusChanged() method as the download proceeds.

Support for multi-value Javadoc options

Gradle has added support for command-line options to doclets that can appear multiple times and have multiple values.

In previous versions of Gradle, it was not possible to supply command-line options like:

-myoption 'foo' 'bar'
-myoption 'baz'

Gradle would produce a single -myoption or combine the option's value into a single argument.

javadoc {
    options {
        def myoption = addMultilineMultiValueOption("myoption")
            [ "foo", "bar" ],
            [ "baz" ]

Use Java home to choose toolchain for cross compilation

For selecting a Java toolchain for cross compilation you can now use ForkOptions.javaHome. Gradle will detect the version of the Java installation and use the right compiler from the installation. Setting ForkOptions.executable has been deprecated in favor of this new way of choosing the Java compiler