Gradle Release Notes

Version 4.8

The Gradle team is pleased to announce Gradle 4.8.

First and foremost, this release of Gradle features dependency locking: a mechanism for locking dependency versions which allows builds to become reproducible in the face of dynamic versions or version ranges. Read the user manual chapter on dependency locking to learn how to take advantage of this exciting new feature.

The publishing plugins get some highly-anticipated improvements in this release:

The maven-publish and ivy-publish plugins are now considered stable and use of the maven plugin is discouraged as it will eventually be deprecated — please migrate.

User experience for incremental annotation processing is improved. Compilation will no longer fail when a processor does something that Gradle detects will not work incrementally. Unused non-incremental processors no longer prevent incremental compilation. Finally, annotation processors are now able to decide dynamically if they are incremental or not. This allows processors with extension mechanisms to check extensions for incrementality before enabling incremental annotation processing.

New native plugins continue to improve with better control over system include path for native compilation and other improvements.

Gradle 4.8 includes Kotlin DSL 0.17.5, bringing the latest Kotlin 1.2.41 release and many improvements to the user experience including location aware runtime error reporting, convenient configuration of nested extensions, faster and leaner configuration time, and TestKit support. At the same time the IntelliJ IDEA Kotlin Plugin fixed many long standing build script editing related issues. See details and examples in the Kotlin DSL v0.17 release notes.

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

Table Of Contents

Upgrade instructions

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

gradle wrapper --gradle-version=4.8

Standalone downloads are available at gradle.org/releases.

New and noteworthy

Here are the new features introduced in this Gradle release.

Locking of dynamic dependencies

Gradle now provides a mechanism for locking dynamic versions. It makes builds reproducible even when declaring dependencies using version ranges.

This enables, amongst others, the following scenarios:

In order to use dependency locking, you first enable it on configurations:

dependencyLocking {
    lockAllConfigurations()
}

You then run a build, telling Gradle to persist lock state:

gradle test --write-locks

From this point onward, for any build where the lock state is available to Gradle, all configurations that have a lock state will resolve the locked versions.

Changes to published dependencies will not impact your build, you will have to re-generate or update the lock before they are considered as dependencies. On the other hand, changes to your build script that would impact the resolved set of dependencies will cause it to fail, ensuring the dependencies do not change without a matching update in the lock file.

Head over to the dependency locking documentation for more details on using this feature.

Signing Publications

The Signing Plugin now supports signing all artifacts of a publication, e.g. when publishing artifacts to a Maven or Ivy repository.

publishing {
  publications {
    mavenJava(MavenPublication) {
      from components.java
    }
  }
}

signing {
  sign publishing.publications
}

Customizing the generated POM

The Maven Publish Plugin now provides a dedicated, type safe DSL to customize the POM generated as part of a Maven publication. The following sample demonstrates some of the new properties and methods. Please see the DSL Reference for the complete documentation.

publishing {
  publications {
    mavenJava(MavenPublication) {
      from components.java
      pom {
        name = "Demo"
        description = "A demonstration of Maven POM customization"
        url = "http://www.example.com/project"
        licenses {
          license {
            name = "The Apache License, Version 2.0"
            url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
          }
        }
        developers {
          developer {
            id = "johnd"
            name = "John Doe"
            email = "john.doe@example.com"
          }
        }
        scm {
          connection = "scm:svn:http://subversion.example.com/svn/project/trunk/"
          developerConnection = "scm:svn:https://subversion.example.com/svn/project/trunk/"
          url = "http://subversion.example.com/svn/project/trunk/"
        }
      }
    }
  }
}

Customizing the generated Ivy module descriptor

The Ivy Publish Plugin now provides a dedicated, type safe DSL to customize the Ivy module descriptor generated as part of an Ivy publication. The following sample demonstrates the new properties and methods. Please see the DSL Reference for the complete documentation.

publishing {
  publications {
    ivyJava(IvyPublication) {
      from components.java
      descriptor {
        license {
          name = "The Apache License, Version 2.0"
          url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
        }
        author {
          name = "Jane Doe"
          url = "http://example.com/users/jane"
        }
        description {
          text = "A concise description of my library"
          homepage = "http://www.example.com/library"
        }
      }
    }
  }
}

Configuration-wide dependency excludes are now published

The Ivy Publish Plugin now writes dependency exclude rules defined on a configuration (instead of on an individual dependency) into the generated Ivy module descriptor; the Maven Publish Plugin now repeats them for each dependency in the generated POM.

Improved incremental annotation processing

This version of Gradle provides the following improvements to incremental annotation processing APIs.

If you maintain a annotation processor, please read the documentation to learn how to enable incremental annotation processing for your library.

Better control over system include path for native compilation

The Gradle Native project continues to improve and evolve the native ecosystem support for Gradle.

TextResources can now be fetched from a URI

Text resources like a common checkstyle configuration file can now be fetched directly from a URI. Gradle will apply the same caching that it does for remote build scripts.

checkstyle {
    config = resources.text.fromUri("http://company.com/checkstyle-config.xml")
}

Create tasks with constructor arguments

You can now create a task and pass values to its constructor. This can be useful for tasks created by plugins that should not be configured directly by users.

In order to pass values to the constructor, the constructor has to be annotated with @javax.inject.Inject. Given the following Task class:

class CustomTask extends DefaultTask {
    final String message
    final int number

    @Inject
    CustomTask(String message, int number) {
        this.message = message
        this.number = number
    }

    @TaskAction
    void doSomething() {
        println("Hello $number $message")
    }
}

You can then create a task, passing the constructor arguments at the end of the parameter list.

tasks.create('myTask', CustomTask, 'hello', 42)

In a Groovy build script, you can create the task using constructorArgs.

task myTask(type: CustomTask, constructorArgs: ['hello', 42])

In a Kotlin build script, you can pass constructor arguments using the reified extension function on the tasks TaskContainer.

tasks.create<CustomTask>("myTask", "hello", 42)

More details are available in the User guide.

Immutable file collections

It is now possible to create immutable file collections by using ProjectLayout.files(Object...). There is also a new method for creating configurable file collections, ProjectLayout.configurableFiles(Object...), which will replace Project.files() in the long run. FileCollections created by ProjectLayout.files() are performing slightly better and should be used whenever mutability is not required. For example, they fit nice when creating tasks with constructor arguments.

CodeNarc upgrade

The default version of CodeNarc used by the codenarc plugin is 1.1.

Ant upgrade

The embedded version of Ant used by Gradle is 1.9.11.

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.

Ivy Publish and Maven Publish Plugins marked stable

The Ivy Publish Plugin and Maven Publish Plugin that have been incubating since Gradle 1.3 are now marked as stable. Both plugins now support signing, publish configuration-wide dependency excludes, and provide new dedicated DSLs for customizing generated POMs or Ivy module descriptors. In addition, some usage quirks with the publishing extension have been addressed which now behaves like other extension objects. Thus, these plugins are now the preferred option for publishing artifacts to Ivy and Maven repositories, respectively.

Fixed issues

Nested afterEvaluate requests are no longer silently ignored

Before this release, afterEvaluate requests happening during the execution of an afterEvaluate callback were silently ignored.

Consider the following code:

afterEvaluate {
    println "> Outer"
    afterEvaluate {
        println "Inner"
    }
    println "< Outer"
}

In Gradle 4.7 and below, it would print:

> Outer
< Outer

With the Inner part being silently ignored.

Starting with Gradle 4.8, nested afterEvaluate requests will be honoured asynchronously in order to preserve the callback execute later semantics, in other words, the same code will now print:

> Outer
< Outer
Inner

Please note that beforeEvaluate and other similar hooks have not been changed and will still silently ignore nested requests, that behaviour is subject to change in a future Gradle release (gradle/gradle#5262).

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.

Deferred configuration of the publishing block

Until Gradle 4.7, the publishing {} block was implicitly treated as if all the logic inside it was executed after the project is evaluated. This caused quite a bit of confusion, because it was the only block that behaved that way. As part of the stabilization effort in Gradle 4.8, we are deprecating this behavior and asking all users to migrate their build.

Please see the migration guide for more information.

Methods on FileCollection

Method on Signature

Signature.getToSignArtifact() should have been an internal API and is now deprecated without a replacement.

SimpleFileCollection

The internal SimpleFileCollection implementation of FileCollection has been deprecated. You should use Project.files() instead.

Use of single test selection system property

The use of a system property to select which tests to execute is deprecated. The built-in --tests filter has long replaced this functionality.

Use of remote debugging test system property

The use of a system property (-Dtest.debug) to enable remote debugging of test processes is deprecated. The built-in --debug-jvm flag has long replaced this functionality.

Overwriting Gradle's built-in tasks

Defining a custom wrapper or init task is deprecated. Please configure the existing tasks instead.

I.e. instead of this:

task wrapper(type:Wrapper) {
    //configuration
}

Do this:

wrapper {
    //configuration
}

Potential breaking changes

Changed behaviour for missing init scripts

In previous releases of Gradle, an init script specified on the command line that did not exist would be silently ignored. In this release, the build will fail if any of the init scripts specified on the command line does not exist.

TaskContainer.remove() now actually removes the task

Previously, calling TaskContainer.remove() didn't actually remove the task but now it does. Since plugins may have accidentally relied on this behavior, please check whether you're calling this method and, if so, verify your plugin works as expected.

Signature.setFile() no longer changes the file to be published

Previously, Signature.setFile() could be used to replace the file used for publishing a Signature. However, the actual signature file was still being generated at its default location. Therefore, Signature.setFile() is now deprecated and will be removed in a future release.

Parsing of exclusions in Maven POM now accepts implicit wildcards

Previously, a Maven POM with an exclusion missing either the groupId or the artifactId was ignored by Gradle. This is no longer the case and thus may cause modules to be excluded from a dependency graph that were previously included.

Changes to the Gradle Kotlin DSL

The Kotlin DSL now respects the JSR-305 package annotations. As a result, annotated Java elements whose types were previously seen as Kotlin platform types, thus non-nullable, will now be seen as effectively either non-nullable or nullable types depending on the JSR-305 annotations. This change could cause script compilation errors.

See the release notes for more information.

Changes to plain console behavior

In Gradle 4.7, the plain console was changed so that task output was grouped and it was easy to determine which task produced a given item of output. With this change, error messages were also grouped and sent to the standard output stream so that they could also be grouped with other task output. Unfortunately, this made it impossible to redirect error messages to a different file handle and while it improved the experience for console users, it worsened the experience for others who preferred to keep error output separate. We have changed this behavior now so that error messages are only grouped on standard output when a console is attached to both standard output and standard error. In all other scenarios, error messages are sent to standard error similar to how they were handled in versions previous to Gradle 4.7.

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.