Gradle Release Notes

Version 4.6-rc-2

The Gradle team is pleased to announce Gradle 4.6.

First and foremost, this release of Gradle includes built-in support for JUnit Platform and the JUnit Jupiter/Vintage Engine, also known as JUnit 5 support. You can use the new filtering and engines functionality in JUnit 5 using the examples provided below and in the documentation.

Also regarding testing, you can now improve your testing feedback loop when running JVM-based tests using the new fail-fast option for Test tasks, which stops the build immediately after the first test failure.

Speaking of annotation processors, it is now more convenient to declare dependencies that are annotation processors through the new annotationProcessor dependency configuration. Using a separate dependency configuration for annotation processors is a best practice for improving performance.

Kotlin DSL v0.15.6 is included in this release of Gradle, and features initialization scripts support, nicer script compilation error reporting, performance improvements, and better IntelliJ IDEA integration. Details are available in the linked release notes.

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

New and noteworthy

JUnit 5 support

JUnit 5 is the latest version of the well-known JUnit test framework. JUnit 5 is composed of several modules:

JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

The JUnit Platform serves as a foundation for launching testing frameworks on the JVM. JUnit Jupiter is the combination of the new programming model and extension model for writing tests and extensions in JUnit 5. JUnit Vintage provides a TestEngine for running JUnit 3 and JUnit 4 based tests on the platform.

Gradle now provides native support for JUnit Jupiter/Vintage Engine on top of JUnit Platform. To enable JUnit Platform support, you just need to add one line to your build.gradle:

You can mix JUnit 3/4 tests with Jupiter tests without the need to rewrite old tests. A sample of mixed tests can be found at samples/testing/junitplatform/engine in the '-all' distribution of Gradle.

Note: Use of JUnit 5 features requires Java 8 or higher.

Fail fast option for Test tasks

Gradle now supports stopping Test tasks after the first failed test. Projects with large test suites can take a long time to execute even though a failure occurred early on leading to unnecessary wait times (especially on CI). To enable this fail fast behavior in your build file, set the failFast property to true:

test { failFast =true}

In addition, this behavior can be enabled from the command line for individual build invocations. An invocation looks like:

Allow declared reasons for dependency and resolution rules

In complex builds, it can become hard to interpret dependency resolution results and why a dependency declaration or a rule was added to a build script. To improve on this situation, we extended all the corresponding APIs with the capability to define a reason for each declaration or rule.

These reasons are shown in dependency insight reports and error messages if the corresponding declaration or rule influenced the resolution result. In the future, they will also be shown in build scans.

In the example, the version of commons-codec that is brought in transitively is 1.9. With the constraint, we express that we need at least 1.11 and Gradle will now pick that version during dependency resolution.

Compared to dependency management rules you can define in the resolution strategy, which are applied after dependency resolution to fix up the result, dependency constraints are declared information that participate in the dependency resolution process. This means that all constraints are considered in combination. For instance, if another dependency brings in an even higher version of commons-codec, Gradle will respect that.

Expressing the same in a traditional dependency substitution rule requires you to repeat part of the dependency resolution process manually – which is expensive and error prone. That is, you would have to inspect the version that was selected and implement a decision based on the version:

Note: Dependency constraints are not yet published, but that will be added in a future release. This means that their use currently only targets builds that do not publish artifacts to maven or ivy repositories.

BOM import

Gradle now provides support for importing bill of materials (BOM) files, which are effectively .pom files that use <dependencyManagement> to control the dependency versions of direct and transitive dependencies. It works by declaring a dependency on a BOM.

Here, for example, the versions of gson and dom4j are provided by the Spring Boot BOM.

Note: This is a Gradle 5.0 feature preview, which means it is a potentially breaking change that will be activated by default in Gradle 5.0. It can be turned on in Gradle 4.6+ by adding enableFeaturePreview('IMPROVED_POM_SUPPORT') in settings.gradle.

Support for optional dependencies in POM consumption

Gradle now creates a dependency constraint for each dependency declaration in a POM file with <optional>true</optional>. This constraint will produce the expected result for an optional dependency: if the dependency module is brought in by another, non-optional dependency declaration, then the constraint will apply when choosing the version for that dependency (e.g., if the optional dependency defines a higher version, that one is chosen).

Note: This is a Gradle 5.0 feature preview, which means it is a potentially breaking change that will be activated by default in Gradle 5.0. It can be turned on in Gradle 4.6+ by adding enableFeaturePreview('IMPROVED_POM_SUPPORT') in settings.gradle.

Compile/runtime scope separation in POM consumption

Since Gradle 1.0, runtime scoped dependencies have been included in the Java compile classpath, which has some drawbacks:

The compile classpath is much larger than it needs to be, slowing down compilation.

The compile classpath includes runtime files that do not impact compilation, resulting in unnecessary re-compilation when these files change.

Now, if this new behavior is turned on, the Java and Java Library plugins both honor the separation of compile and runtime scopes. Meaning that the compile classpath only includes compile scoped dependencies, while the runtime classpath adds the runtime scoped dependencies as well. This is in particular useful if you develop and publish Java libraries with Gradle where the api/implementation dependencies separation is reflected in the published scopes.

Note: This is a Gradle 5.0 feature preview, which means it is a potentially breaking change that will be activated by default in Gradle 5.0. It can be turned on in Gradle 4.6+ by adding enableFeaturePreview('IMPROVED_POM_SUPPORT') in settings.gradle.

Customizable metadata file resolution

Gradle now allows you to explicitly state for which metadata files it should search in a repository. Use the following to configure Gradle to fail-fast resolving a dependency if a POM file is not found first.

Tasks API allows custom command-line options

Sometimes a user wants to declare the value of an exposed task property on the command line instead of the build script. Being able to pass in property values on the command line is particularly helpful if they change more frequently. With this version of Gradle, the task API now supports a mechanism for marking a property to automatically generate a corresponding command line parameter with a specific name at runtime. All you need to do is to annotate a setter method of a property with Option.

The following examples exposes a command line parameter --url for the custom task type UrlVerify. Let's assume you wanted to pass a URL to a task of this type named verifyUrl. The invocation looks as such: gradle verifyUrl --url=https://gradle.org/. You can find more information about this feature in the documentation on declaring command-line options.

Logging options for debugging build caching

This version of Gradle introduces a property org.gradle.caching.debug which causes individual input property hashes to be logged on the console. For example, when running gradle compileJava -Dorg.gradle.caching.debug=true --build-cache the output would be:

In earlier versions of Gradle, this output was logged on the INFO log level. This does not happen anymore, and the --info logs should be much less verbose now while the build cache is enabled.

Caching for Scala compilation when using the play plugin

The task PlatformScalaCompile is now cacheable. This means that Play projects written in Scala now also benefit from the build cache!

Improved Visual Studio IDE support for multi-project builds

Previous versions of Gradle would only generate Visual Studio solution files for a given component and its dependencies. This made it difficult to work on multiple components in a build at one time as a developer would potentially need to open multiple Visual Studio solutions to see all components. When the visual-studio plugin is applied, Gradle now has a visualStudio task on the root project that generates a solution for all components in the multi-project build. This means there is only one Visual Studio solution that needs to be opened to be able to work on any or all components in the build.

Improvements in gradle-native plugins

The gradle-native has been working on adding new features for building with native languages (like C++). As mentioned above, Gradle now generates a single Visual Studio solution for a multi-project build. Other unannounced features have continued to be developed, which we hope to detail in a future blog post.

Highlights to the gradle-native plugins will continue to be mentioned in Gradle's release notes, but more information will be provided in the gradle-native release notes.

Honour cache-expiry settings in the presence of detached configurations

Gradle allows dependency cache expiry (i.e cacheChangingModulesFor) to be set on a per-configuration basis. However, due to a bug in previous versions of Gradle, if a dependency was first resolved via a configuration using the default (24hr) expiry settings, any other resolve in the same build invocation would get the same result.

Normally this wouldn't be a big deal, since most users set the same expiry everywhere using configurations.all. The catch is that plugins like io.spring.dependency-management use detached configurations, which are excluded from configurations.all. If a build was using one of these plugins, the detached configuration could be resolved first, causing later resolves to obtain the same (possibly stale) result.

Default JaCoCo version upgraded to 0.8.0

Promoted features

Promoted features are features that were incubating in previous versions of Gradle but are now supported and subject to backwards compatibility. See the User guide section on the “Feature Lifecycle” for more information.

The following are the features that have been promoted in this Gradle release.

Build cache and task output caching marked stable

The build cache and task output caching were first introduced in Gradle 3.5. They are used in production by different teams, including the Gradle team itself, with great results. As of Gradle 4.6, the build cache and task output caching are no longer incubating and considered public features.

TestKit marked stable

TestKit was first introduced in Gradle 2.6 to support developers with writing and executing functional tests for plugins. In the course of the Gradle 2.x releases, a lot of new functionality was added. This version of Gradle removes the incubating status and makes TestKit a stable feature.

CompileOptions.annotationProcessorPath property

The CompileOptions.annotationProcessorPath property has been promoted and is now stable.

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 5.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.

Putting processors on the compile classpath or using an explicit -processorpath compiler argument has been deprecated and will be removed in Gradle 5.0. Annotation processors should be added to the annotationProcessor configuration instead. If you don't want any processing, but your compile classpath contains a processor unintentionally (e.g. as part of some library you use), use the -proc:none compiler argument to ignore it.

Play 2.2 is deprecated in Play plugin

The use of Play 2.2 with the the Play plugin has been deprecated and will be removed with Gradle 5.0. It is highly recommended to upgrade to a newer version of Play.

CompilerArgumentProvider replaced by CommandLineArgumentProvider

Potential breaking changes

Local build cache directory cleanup is now time-based

Previously, Gradle would clean up the local build cache directory only if the size of its contents reached 5 GB, or whatever was configured in targetSizeInMB. From now on Gradle will instead clean up everything older than 7 days, regardless of the size of the cache directory. As a consequence targetSizeInMB is now deprecated, and changing its value has no effect.

Added annotationProcessor configurations

The java-base plugin will now add an <sourceSetName>AnnotationProcessor configuration for each source set. This might break when the user already defined such a configuration. We recommend removing your own and using the configuration provided by java-base.

Removed Visual Studio IDE tasks

There are no longer tasks to generate Visual Studio solution files for each component in the build. There is now only a single task (visualStudio) in the root project that generates a solution containing all components in the build.

Removed StartParameter.taskOutputCacheEnabled

The deprecated property StartParameter.taskOutputCacheEnabled has been removed. Use StartParameter.buildCacheEnabled instead.

HttpClient library upgraded to version 4.5.5

Kotlin Standard Library for Java 8 artifact changes

Gradle now bundles the Kotlin Standard Library Java 8 artifact kotlin-stdlib-jdk8 instead of kotlin-stdlib-jre8 as a follow up to the upgrade to Kotlin 1.2. This change might affect your build, please see the Kotlin documentation about this change.

External contributions

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