# Gradle Release Notes

### Version 4.6

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.

Thank you to the JUnit team for helping to achieve JUnit Platform support, and a special thank you to Andrew Oberstar for extraordinary contributions toward this effort.

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.

    // Example JUnit 5 and fail-fast test configuration
    test {
        useJUnitPlatform {
            excludeTags 'slow'
            includeEngines 'junit-jupiter', 'junit-vintage'
        }

        failFast = true
    }

Moving on to dependency management improvements: you can now declare dependency constraints for transitive dependencies and avoid problems caused by oft-hidden upstream dependency changes.

This release also features enhanced Maven dependency compatibility: support for importing BOMs, optional dependencies, and compile/runtime separation when consuming POMs. For now you must enable these features by adding `enableFeaturePreview('IMPROVED_POM_SUPPORT')` to your settings.gradle file, as they break backward compatibility in some cases.

This version of Gradle also comes with a couple especially useful new APIs for task development. You can now declare custom command-line flags for your custom tasks, for example: `gradle myCustomTask --myfoo=bar`. In addition, tasks that extend `Test`, `JavaExec` or `Exec` can declare rich arguments for invoking the underlying executable. This allows for better modeling of tools like annotation processors.

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.

## Table Of Contents

## Upgrade instructions

Switch your build to use Gradle 4.6 quickly by updating your wrapper properties:

    gradle wrapper --gradle-version=4.6

Standalone downloads are available at gradle.org/releases.

## New and noteworthy

Here are the new features introduced in this Gradle release.

### 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`:

    test {
        useJUnitPlatform()
    }

Moreover, Tagging and Filtering can be enabled via:

    test {
        useJUnitPlatform {
            // includeTags 'fast'
            excludeTags 'slow'

            // includeEngines 'junit-jupiter', 'junit-vintage'
            // excludeEngines 'custom-engine'
        }
    }

You can find more information on test grouping and filtering in the Java Plugin documentation.

#### JUnit Jupiter Engine

To enable `JUnit Jupiter` support, add the following dependencies:

    dependencies {
        testImplementation 'org.junit.jupiter:junit-jupiter-api:5.1.0'
        testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.0'
    }

Put your first `Jupiter` test into `src/test/java/foo/bar`:

    package foo.bar;

    import org.junit.jupiter.api.Test;

    public class JUnitJupiterTest {
        @Test
        public void ok() {
        }
    }

Now you can run `gradle test` to see the results of your JUnit 5 tests!

You can find a sample of test with `JUnit Jupiter` at `samples/testing/junitplatform/jupiter` in the '-all' distribution of Gradle.

#### JUnit Vintage Engine

If you want to run JUnit 3/4 tests on `JUnit Platform`, you should add extra `JUnit Vintage Engine` dependency:

    test {
        useJUnitPlatform()
    }

    dependencies {
        testCompileOnly 'junit:junit:4.12'
        testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.1.0'
    }

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:

    gradle integTest --fail-fast

More information is available in the Java Plugin documentation for test execution.

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

    dependencies {
        implementation('org.ow2.asm:asm:6.0') {
            because 'we require a JDK 9 compatible bytecode generator'
        }
    }

### Dependency constraints for transitive dependencies

With dependency constraints, Gradle adds a mechanism to express constraints over transitive dependencies which are used during dependency resolution.

    dependencies {
        implementation 'org.apache.httpcomponents:httpclient'
    }

    dependencies {
        constraints {
            implementation('org.apache.httpcomponents:httpclient:4.5.3') {
                because 'previous versions have a bug impacting this application'
            }
            implementation('commons-codec:commons-codec:1.11') {
                because 'version 1.9 pulled from httpclient has bugs affecting this application'
            }
        }
    }

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:

    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        if (details.requested.group == 'commons-codec'
            && details.requested.name == 'commons-codec'
            && VersionNumber.parse(details.requested.version) < VersionNumber.parse('1.11')) {
                details.useVersion '1.11'
        }
    }

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.

    dependencies {
        // import a BOM
        implementation 'org.springframework.boot:spring-boot-dependencies:1.5.8.RELEASE'

        // define dependencies without versions
        implementation 'com.google.code.gson:gson'
        implementation 'dom4j:dom4j'
    }

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.

    repositories {
         mavenCentral {
             metadataSources {
                 mavenPom() // Look for Maven '.pom' files
                 // artifact() - Do not look for artifacts without metadata file
             }
         }
    }

This avoids a 2nd request for the JAR file when the POM is missing, making dependency resolution from Maven repositories faster in this case.

### Convenient declaration of annotation processor dependencies

It is now even easier to add annotation processors to your Java projects. Simply add them to the `annotationProcessor` configuration:

    dependencies {
        annotationProcessor 'com.google.dagger:dagger-compiler:2.8'
        implementation 'com.google.dagger:dagger:2.8'
    }

Declaring annotation processors on a separate configuration improves performance by preserving incremental compilation for tasks that don't require annotation processors.

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

    import org.gradle.api.tasks.options.Option;

    public class UrlVerify extends DefaultTask {
        private String url;

        @Option(option = "url", description = "Configures the URL to be verified.")
        public void setUrl(String url) {
            this.url = url;
        }

        @Input
        public String getUrl() {
            return url;
        }

        @TaskAction
        public void verify() {
            getLogger().quiet("Verifying URL '{}'", url);

            // verify URL by making a HTTP call
        }
    }

### Rich command-line arguments for Test, JavaExec or Exec tasks

Gradle 4.5 added the possibility to add `CommandLineArgumentProvider`s to `CompileOptions`, thus enabling plugin authors to better model tools like annotation processors.

Now we introduce `CommandLineArgumentProvider`s to `Exec`, `JavaExec` and `Test`, both to model command line arguments (`Exec` and `JavaExec`) as well as JVM options (`JavaExec` and `Test`).

For example, the built-in `jacoco` plugin uses this new feature to declare the inputs and outputs of the JaCoCo agent added to the test task.

    class JacocoAgent implements CommandLineArgumentProvider {

        private final JacocoTaskExtension jacoco;

        public JacocoAgent(JacocoTaskExtension jacoco) {
            this.jacoco = jacoco;
        }

        @Nested
        @Optional
        public JacocoTaskExtension getJacoco() {
            return jacoco.isEnabled() ? jacoco : null;
        }

        @Override
        public Iterable<String> asArguments() {
            return jacoco.isEnabled() ? ImmutableList.of(jacoco.getAsJvmArg()) : Collections.<String>emptyList();
        }

    }

    task.getJvmArgumentProviders().add(new JacocoAgent(extension));

For this to work, JacocoTaskExtension needs to have the correct input and output annotations.

See the documentation about tasks with nested inputs for information how to leverage this feature in custom plugins.

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

    > Task :compileJava
    Appending taskClass to build cache key: org.gradle.api.tasks.compile.JavaCompile_Decorated
    Appending classLoaderHash to build cache key: 0e1119759d236086191ff6fbd26c610f
    Appending actionType to build cache key: _BuildScript_$_run_closure1_769114ba780efdb8aed68d70a323d160
    Appending actionClassLoaderHash to build cache key: c383666cbb0f1bf25d832b944f228c44
    Appending actionType to build cache key: org.gradle.api.tasks.compile.JavaCompile_Decorated
    Appending actionClassLoaderHash to build cache key: 0e1119759d236086191ff6fbd26c610f
    Appending inputPropertyHash for 'options.class' to build cache key: 74824162f3f111308fa9dc95c82b65a6
    Appending inputPropertyHash for 'options.compilerArgs' to build cache key: 8222d82255460164427051d7537fa305
    ...
    Appending inputPropertyHash for 'source' to build cache key: 55786645cf0e6dcf6a3d48b1b43bf687
    Appending outputPropertyName to build cache key: destinationDir
    Build cache key for task ':compileJava' is 2221655c6648a7e9baf61a6234de8658

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.

### Documentation updates

Documentation in this release of Gradle has significantly improved in the following areas:

- Dependency management, especially regarding managing dependency configurations and understanding terminology
- Troubleshooting
- Installation

Please reach out to @gradle on Twitter or through GitHub to provide feedback to help ensure improvements are useful for you.

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

This nasty cache-expiry bug has now been fixed. Users can trust that Gradle will return the most up-to-date `SNAPSHOT` or version available as long as the dependency cache expiry is set correctly.

### Default JaCoCo version upgraded to 0.8.0

The JaCoCo plugin has been upgraded to use JaCoCo version 0.8.0 by default.

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

Note that the SPI to implement your own build cache service stays incubating.

### 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 annotation processors on the compile classpath or explicit `-processorpath` compiler argument

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`

The interface `CompilerArgumentProvider` has been deprecated. Use `CommandLineArgumentProvider` instead.

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

The minimum age for entries to be cleaned up can now be configured in `settings.gradle` via the `removeUnusedEntriesAfterDays` property:

    buildCache {
        local {
            removeUnusedEntriesAfterDays = 30
        }
    }

### 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`.

### Changes to Visual Studio IDE configuration

`VisualStudioExtension` no longer has a `solutions` property. There is now only a single solution for a multi-project build that can be accessed through the `VisualStudioRootExtension` on the root project. For instance:

    model {
        visualStudio {
            solution {
                solutionFile.location = "vs/${name}.sln"
            }
        }
    }

### 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

Gradle has been upgraded to embed HttpClient version 4.5.5 over 4.4.1.

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

- Andrew Oberstar - Spike multiple JUnit 5 implementations (gradle/gradle#3886)
- Thomas Broyer - Add annotationProcessor configuration for each source set (gradle/gradle#3786)
- Sergei Dryganets - Improved gpg instructions in signing plugin documentation (gradle/gradle#4023)
- Kevin Macksamie - Fix xref id to java-gradle-plugin section of user guide (gradle/gradle#4179)
- Devi Sridharan - Make `PlatformScalaCompile` cacheable (gradle/gradle#3804)

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.