Gradle Release Notes

Version 3.2

The Gradle team is pleased to announce Gradle 3.2.

It's a relatively quiet release this time around, but there are still plenty of reasons to upgrade.

Perhaps the most significant improvements are in the incremental build support, which now has better up-to-date checking for Java compilation, copying, and archiving. You can also have Gradle treat any task input as a classpath with the new @Classpath annotation.

Users of Gradle's native build support gain an important tool in this release. Many of you will be familiar with the buildDependents task for classic multi-project builds. This is now available in native builds as well via new assembleDependents and buildDependents tasks. These are incredibly useful for determining whether your changes have adversely impacted anything that depends on them.

If you use an IDE and have a lot of dependencies in your build—particular dynamic ones—you may have experienced long import times. The underlying issue has been fixed in this release, resulting in significantly improved import times. One example enterprise build showed a 100-fold improvement!

Our users trialling the Kotlin build script support will be glad to hear that progress continues apace with support for multi-project builds. And it's easier to try this feature on Windows now that a bug in compiling scripts on that platform has been fixed.

Gradle 3.1 fixed the behavior of Ctrl-C for many scenarios, but it would still kill the daemon if you used it during the first build run on that daemon. The situation has now improved with this release so that Ctrl-C won't always kill the daemon on the first run. See the dedicated section later for a more complete description of the latest behavior.

The last change we want to bring to your attention has been a long time coming and will affect a large number of builds: the shortcut syntax for declaring tasks (via <<) has now been deprecated. The eagle-eyed among you will notice that the user guide examples have been updated to use doLast() and we strongly recommend that you follow suit. This feature will be removed in Gradle 5.0! See the Deprecations section for more details.

Table Of Contents

New and noteworthy

Here are the new features introduced in this Gradle release.

Incremental build improvements

Gradle's incremental build support continues to see improvements, particularly in the area of more accurate up-to-date checks.

Java compilation tracks Java version used

Gradle's Java plugin has taken account of the sourceCompatibility and targetCompatibility versions for a while now with respect to working out whether compiled class files are up to date or not. But the version of the Java compiler used was ignored.

This release fixes that, which means changing the Java compiler version—say from Java 7 to Java 8—will now result in recompilation.

Better change tracking in copy and archive tasks

A long-standing issue with copy-based tasks has now been fixed: the destination directory is finally taken into account for the tasks' up-to-date checks. So changing the into value will result in the task running again.

In addition, Gradle now tracks changes to case-sensitivity, duplication strategy, file mode and dir mode on child specs, not just the main one.

Classpath tracking

Input properties that should be treated as Java classpaths can now be annotated with @Classpath. This allows the task to ignore irrelevant changes to the property, such as different names for the same files. It is similar to annotating the property with @OrderSensitive and @PathSensitive(RELATIVE), but it will also ignore the names of JAR files directly added to the classpath.

Removing all sources will delete outputs

For a long time Gradle supported skipping the execution of a task entirely if it didn't have any sources. This feature can be enabled by annotating an input file or file collection property with @SkipWhenEmpty. In previous versions of Gradle, removing all of a task's input files would leave the previous build execution's outputs in place on subsequent runs. This is now fixed: stale outputs are properly removed.

Build Dependents for Native Binaries

Sometimes, you may need to assemble (compile and link) or build (compile, link and test) a component or binary and its dependents (things that depend upon the component or binary). The native software model now provides tasks that enable this capability.

First, the dependentComponents task generates a report that gives insight about the relationships between each component.

Second, the buildDependents* and assembleDependents* tasks allow you to assemble or build a component and its dependents in one step.

See the User guide section on “Assembling or building dependents“ in the “Building native software“ chapter for more information.

New preferProjectModules() conflict resolution strategy for multi-project builds

The preferProjectModules() configuration option can now be used in multi-project builds.

configurations.all.resolutionStrategy.preferProjectModules()

With this option it is possible to tell Gradle to always resolve a project dependency to a subproject, if the corresponding subproject exists in the build. Without this option, other dependencies to a higher version of the same module cause the replacement of the subproject by the other version in the dependency tree.

Improved deprecation warnings

When a line in a build script triggers a deprecation warning, Gradle now prints its location to the console. You can also pass the command line option -s or -S to get the whole stack trace.

The improved log message should make it much easier to spot and fix those warnings, as demonstrated by this sample output:

> gradle tasks
The Jetty plugin has been deprecated and is scheduled to be removed in Gradle 4.0. Consider using the Gretty (https://github.com/akhikhl/gretty) plugin instead.
        at build_dhrhtn4oo56t198zc6nkf59c4.run(/home/someuser/project-dir/build.gradle:3)
...

This is particularly important now that the shortcut syntax for task definitions (<<) has been deprecated!

HTTP Basic Authentication for wrapper distributions

The Gradle Wrapper can now download Gradle distributions from a server that requires authentication. This allows you to host the Gradle distribution on a private server protected with HTTP Basic Authentication.

See the User guide section on “authenticated distribution download“ for more information.

As stated in the User guide, please note that this shouldn't be used over insecure connections.

Ctrl-C no longer stops the Daemon on first run

We made a number of improvements in Gradle 3.1 that allow the Daemon to cancel a running build when a client disconnects unexpectedly. This included many scenarios in which the user pressed Ctrl-C, but not all. Pressing Ctrl-C or sending a SIGINT would always result in Gradle killing the daemon during the first build execution on that daemon.

This release fixes the problem so that Gradle will always attempt to cancel the build, even during the first build run. If the build can be successfully canceled, the daemon remains available for subsequent builds. However, if the build is unresponsive and cannot be canceled, then Gradle will kill the daemon to ensure that the system resources are properly reclaimed.

Multi-project builds with Kotlin scripting

This release ships with Gradle Script Kotlin v0.4.0.

v0.4.0 improves support for multi-project builds of Kotlin based projects, enables the usage of Gradle Script Kotlin extensions to the Gradle API in buildSrc and fixes Kotlin build script compilation on Windows.

See the Gradle Script Kotlin v0.4.0 release notes for the details.

Fixed issues

Fixed a performance problem in the Tooling API

The dependency resolution caches were not being filled when building Tooling API models. As a result, IDE import was very slow when the caches were cold. This especially affected builds with many dynamic dependencies and low cache timeouts. One large enterprise project saw import times drop by a factor of 100.

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 left shift operator on the Task interface

The left shift (<<) operator acts as an alias for adding a doLast action to an existing task. For newcomers to Gradle, the meaning of the operator is not immediately apparent and leads to mixing configuration code with action code. Such misconfigured tasks lead to unexpected runtime behavior.

Let's consider the following two examples to illustrate some common mistakes:

With this version of Gradle, the left shift operator on the Task interface is deprecated and is scheduled to be removed with the next major release. There's no direct replacement for the left shift operation. Please use the existing methods doFirst and doLast to define task actions.

Modifying a child copy spec during task execution

As a consequence of improved change tracking in copy and archive tasks, we have deprecated the ability to modify a copy spec during the execution phase. These changes are not tracked since Gradle determines the inputs and outputs of a task before executing it.

For example, the following will now create a deprecation warning:

task myCopy(type: Copy) {
    from ("some-dir")
    into ("build/output")

    doFirst {
        // DEPRECATED
        from ("some-other-dir") {
            exclude "excluded-file"
        }
    }
}

The simple solution is to move the from into the configuration phase:

task myCopy(type: Copy) {
    from ("some-dir")
    into ("build/output")
    from ("some-other-dir") {
        exclude "excluded-file"
    }
}

If you can't do that because something must be calculated during the build (e.g. dependency resolution), then you can use a configuration task:

task configureCopy {
    doLast {
        myCopy.from ("some-other-dir") {
            exclude "excluded-file"
        }
    }
}
task myCopy(type: Copy, dependsOn: configureCopy) {
    from ("some-dir")
    into ("build/output")
}

Potential breaking changes

Tooling API builders run before buildFinished listeners

Tooling API model builders are now executed before any buildFinished listeners have been notified.

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.

Usage of Jansi library embedded with Java annotation processor

Issue #778 reported a failed build with a crashed daemon JVM if a Java annotation processor is used that embeds an older version of Jansi than the one bundled with Gradle. As a workaround you can execute the Java compiler in a forked process.

tasks.withType(JavaCompile) { 
    options.fork = true 
}