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.

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: Companies dealing with multi repositories no longer need to rely on -SNAPSHOT or changing dependencies, which sometimes result in cascading failures when a dependency introduces a bug or incompatibility. Now dependencies can be declared against major or minor version range, enabling to test with the latest versions on CI while leveraging locking for stable developer builds.

or changing dependencies, which sometimes result in cascading failures when a dependency introduces a bug or incompatibility. Now dependencies can be declared against major or minor version range, enabling to test with the latest versions on CI while leveraging locking for stable developer builds. Teams that want to always use the latest of their dependencies can use dynamic versions, locking their dependencies only for releases. The release tag will contain the lock files, allowing that build to be fully reproducible when bug fixes need to be developed. 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. Compilation will no longer fail when a processor does something that Gradle knows won't work incrementally. Instead Gradle will simply do a full recompile and inform the user about the problem.

Unused non-incremental processors will no longer prevent incremental compilation. This means that incremental and non-incremental processors can be safely packaged together. As long as the user doesn't use the non-incremental processor in their code, everything will remain incremental.

Processors will be able to decide dynamically if they are incremental or not. Some annotation processors have extension mechanisms that first need to check all extensions for incrementality before they can opt-in. This new mechanism will supersede the META-INF registration. 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. FileCollection s 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 .

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 FileCollection.add() is now deprecated. Use ConfigurableFileCollection.from() instead. You can create a ConfigurableFileCollection via Project.files() .

is now deprecated. Use instead. You can create a via . FileCollection.stopExecutionIfEmpty() is deprecated without a replacement. You can use @SkipWhenEmpty on a FileCollection property, or throw a StopExecutionException in your code manually instead. 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 ) { } Do this: wrapper { }

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.