Gradle Release Notes

Version 3.3

The Gradle team is pleased to announce Gradle 3.3.

This release of Gradle makes the gradle tasks report much faster for medium-to-large projects. By default, gradle tasks will now only display tasks which have been assigned a task group. For example, execution time was reduced from 554 seconds to 3 seconds on our perf-enterprise-large benchmark project — over 100x faster! See the technical details on how and why this change was made further down.

It is now possible to compile native applications using Visual Studio 2015. Gradle will locate the Universal C Runtime required by the Visual C++ toolchain.

Kotlin build script support has further improved with faster startup performance, increased API parity with Groovy-based build scripts, and better interoperability with Groovy plugins. See the gradle-script-kotlin v0.5.0 release notes for details.

Scala compilation startup time in large multi-project builds has been improved through enhancements to Gradle's integration with the Zinc Scala compiler. In earlier versions of Gradle, builds with many Scala projects could timeout and fail when building in parallel.

Tooling API generates more progress events. This means that IDEs will show a much clearer picture of what Gradle is doing during the configuration phase, resolving dependencies, and using composite builds. Details and pictures below.

The Gradle GUI has been deprecated and will be removed in Gradle 4.0. An IDE which provides a UI for Gradle — IntelliJ IDEA, Eclipse, or NetBeans, for example, is recommended.

Heads up: If you use the Gradle Wrapper and previously generated the wrapper with Gradle 3.2, re-run ./gradlew wrapper to avoid a mis-configured wrapper script.

Table Of Contents

New and noteworthy

Here are the new features introduced in this Gradle release.

Improved performance of tasks report

In previous versions of Gradle, the tasks report suffered from poor execution performance especially in large multi-project builds with many sub projects. Previously, the gradle tasks report would generate and traverse the task graph to find edge nodes — this intelligence came at great performance cost for medium-to-large projects. This version of Gradle improves the tasks report generation performance significantly. In the wake of this change, the report now renders tasks based on different rules. By default, the report shows only those tasks which have been assigned to a task group, so-called visible tasks. Tasks which have not been assigned to a task group, so-called hidden tasks, can be included in the report by enabling the command line option --all. Task dependencies are not rendered as indented task nodes anymore.

For Gradle's own build the time to print the task report dropped from 55s to 4s thanks to this change.

Visual Studio 2015 Support

It is now possible to compile native applications with the Visual C++ toolchain packaged with all versions of Visual Studio 2015. With this release, Gradle will locate the Universal C Runtime required by the Visual C++ toolchain.

Kotlin Build Scripts

Gradle Script Kotlin v0.5.0, included in Gradle 3.3, greatly improves startup performance by caching compiled build script classes. Updates since v0.4.1:

Full details are available in the Gradle Script Kotlin v0.5.0 release notes.

Improved initial Scala compilation performance

Previously, large multi-project Scala builds suffered from poor startup performance due to how the Zinc compiler interface was generated and file locking around it. Fedor Korotkov kindly contributed a smarter locking strategy that improves performance and prevents cache pollution from using different versions of Zinc in one build. Thank you, Fedor!

When generating project reports with the Project Reports Plugin, Gradle now displays a click-able URL.

Incremental build improvements

Custom task property annotations can be overridden in subclasses

In previous versions of Gradle, a custom task class overriding a property from a base class couldn't reliably change the type of the property via annotations used for incremental builds. Gradle now chooses the annotation based on the class hierarchy so that subclasses can override a parent class's annotation. A subclass can turn an @InputFiles property into a @Classpath property or an @OutputFile property into an @OutputDirectory property or any other combination. This can be useful when extending or working around problems with custom tasks that you do not control.

class ThirdPartyBrokenTask extends DefaultTask {
    @Input File inputFile // wrong, task depends on the contents of this file, not just the path.
    @OutputDirectory File outputDir
    @TaskAction void generate() { ... }
}

class FixedTask extends ThirdPartyBrokenTask {
    @InputFile File inputFile // fixed, property is appropriately annotated as an input.
}

In the above example, the contents of FixedTask.inputFile will be used in up-to-date checks.

@OutputFiles and @OutputDirectories are allowed on Map properties

It is now possible to declare multiple task outputs with names from a single task property. Most tasks use singular output annotations (@OutputFile or @OutputDirectory) and are unaffected by this change.

This change allows a plugin author to identify each output uniquely, so Gradle can accurately capture and restore a task's outputs when used with the upcoming build cache feature. Tasks declaring @OutputFiles or @OutputDirectories as FileCollections (or any other type not implementing Map) will continue to work, but they will exclude the task from output caching.

Example:

class CustomTask extends DefaultTask {
    @OutputFiles
    Map<String, File> outputFiles
    // ...
}

From the Gradle DSL, output files and directories can be registered with names using the pre-existing TaskOutputs.files() and the new TaskOutputs.dirs() methods via a Map. As with other similar methods, the values of the Map are resolved according to Project.file().

It is also possible to pass a Callable, such as a Groovy Closure, returning a Map for lazy evaluation:

task customTask {
    outputs.files({ 
        first: "one.txt", 
        second: "two.txt" 
    }).withPropertyName("outputFiles")
}

Tasks loaded via custom classloaders are never considered UP-TO-DATE

Since 3.0 Gradle tracks the implementation of a task's type, and marks tasks out-of-date when it detects changes. But it can only do this reliably with task types that were loaded via Gradle's own classloaders. From this version Gradle will always mark tasks loaded via custom classloaders as out-of-date. This also applies to tasks that have custom actions attached that were loaded via a custom classloader.

Tooling API generates more progress events

The Tooling API now generates progress events for more build activity:

This means that IDEs will show a much clearer picture of what Gradle is doing during configuration, dependency resolution, and using composite builds.

Before: