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.
preferProjectModules()
conflict resolution strategy for multi-project buildsHere are the new features introduced in this Gradle release.
Gradle's incremental build support continues to see improvements, particularly in the area of more accurate up-to-date checks.
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.
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.
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.
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.
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.
preferProjectModules()
conflict resolution strategy for multi-project buildsThe 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.
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!
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.
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.
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.
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.
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 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:
A build configures the description
property and defines an action using the left shift operator. As a result, the task would not configure the task's description.
// WRONG: Description assigned in execution phase
task helloWorld << {
description = 'Prints out a message.'
println 'Hello world!'
}
// CORRECT: Description assigned in configuration phase
task helloWorld {
description = 'Prints out a message.'
doLast {
println 'Hello world!'
}
}
A build defines a typed task using the left shift operator. As a result, the task is always UP-TO-DATE
as the inputs and outputs of the task are configured during the execution phase.
// WRONG: Configuring task in execution phase
task copy(type: Copy) << {
from 'source'
into "$buildDir/output"
}
// CORRECT: Configuring task in configuration phase
task copy(type: Copy) {
from 'source'
into "$buildDir/output"
}
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.
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")
}
Tooling API model builders are now executed before any buildFinished
listeners have been notified.
We would like to thank the following community members for making contributions to this release of Gradle.
ShadedJar.java
under buildSrc
javax.net.ssl.trustStore
for HTTP resource access over TLSpreferProjectModules()
option to dependency resolution strategyWe love getting contributions from the Gradle community. For information on contributing, please see gradle.org/contribute.
Known issues are problems that were discovered post release that are directly related to changes made in this release.
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
}