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 projectover 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:

Before

After:

After

Task to create Java properties files

The new WriteProperties task is available to create Java properties files in a reproducible manner. For more information see the User guide section on "Properties files".

Fixed issues

Deprecations

Features that have become superseded or irrelevant due to the natural evolution of Gradle become deprecated, and scheduled to be removed in the next major Gradle version (Gradle 4.0). See the User guide section on the “Feature Lifecycle” for more information.

The following are the newly deprecated items in this Gradle release. If you have concerns about a deprecation, please raise it via the Gradle Forums.

The Ant-based Java compiler itself was removed in Gradle 2.0. We now have deprecated the Ant-based <depend/> task support as well. These properties will be removed in Gradle 4.0.

Deprecated methods and annotations

The Gradle GUI

The Gradle GUI has been deprecated and will be removed in Gradle 4.0. Consider using an IDE with support for Gradle e.g. Eclipse, IntelliJ or NetBeans instead.

Potential breaking changes

Incompatibilities introduced by internal API changes in 3.2

In Gradle 3.2, an internal API leaked into the public API and caused some plugins built with Gradle 3.2 and 3.2.1 to inadvertently use an internal type that made the plugins incompatible with all Gradle releases. Only plugins that call task.getInputs().file(), task.getInputs().files() or task.getInputs().dir() directly are impacted. When an incompatible plugin is used, the Gradle build will fail with a NoSuchMethodError error.

This release restores the public type on the TaskInputs API. Plugins built with Gradle 3.3 should be compatible with all earlier 3.x releases.

Plugins that must continue to use Gradle 3.2 or 3.2.1 can avoid this binary incompatibility problem by using custom annotations instead of the programmatic getInputs() API when adding inputs to their tasks. There is no way to fix the problem without recompilation.

BuildInvocations model is always returned for the connected project

In previous Gradle versions, when connected to a sub-project and asking for the BuildInvocations model using a ProjectConnection, the BuildInvocations model for the root project was returned instead. Gradle will now return the BuildInvocations model of the project that the ProjectConnection is connected to.

Java Test task does not track working directory as input

Previously changing the working directory for a Test task made the task out-of-date. Changes to the contents had no such effect: Gradle was only tracking the path of the working directory. Tracking the contents would have been problematic since the default working directory is the project directory.

Most tests don't rely on the working directory at all and those that do depend on its contents.

From Gradle 3.3, the working directory is not tracked at all. Due to this, changing the path of the working directory between builds won't make the task out-of-date.

If it's needed, the working directory can be added as an explicit input to the task, with contents tracking:

test {
    workingDir "$buildDir/test-work"
    inputs.dir workingDir
}

To restore the previous behavior of tracking only the path of the working directory:

test {
    inputs.property "workingDir", workingDir
}

Order of task property annotations from hierarchy

The annotated type of a property (@InputFile, @OutputFile, etc) for a custom task is now determined by the class hierarchy when conflicting types are present. In previous Gradle releases, the way the conflict was resolved was unspecified. This change affects incremental builds and may cause Gradle to treat a property as a different kind of input or output than it did.

See Incremental build improvements above for an example.

LenientConfiguration.getFiles() returns the same set of files as other dependency query methods

There are several different methods you can use to query the set of files for the dependencies defined for a Configuration. One such method is LenientConfiguration.getFiles(). In previous versions of Gradle this method would not include files defined by file dependencies. These are dependencies that are declared using a FileCollection, such as:

dependencies {
    compile fileTree(dir: 'some-dir', include: '**/*.jar')
}

In this version of Gradle, LenientConfiguration.getFiles() now includes these files in the result. This change makes this method consistent with other query methods such as ResolvedConfiguration.getFiles() or Configuration.getFiles().

External contributions

We would like to thank the following community members for making contributions to this release of Gradle.

We love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.

Known issues

Known issues are problems that were discovered post release that are directly related to changes made in this release.