This chapter provides the information you need to migrate your older Gradle 4.x builds to Gradle 5.0. In most cases, you will need to apply the changes from all versions that come after the one you’re upgrading from. For example, if you’re upgrading from Gradle 4.3, you will also need to apply the changes since 4.4, 4.5, etc.

💡
If you are using Gradle for Android, you need to move to version 3.4 or higher of both the Android Gradle Plugin and Android Studio.

We recommend the following steps for all users:

  1. If you are not already on version 4.10.2, read the sections below for help upgrading your project to 4.10.2.

  2. Try running gradle help --scan and view the deprecations view of the generated build scan. If there are no warnings, the Deprecations tab will not appear.

    Deprecations View of a Gradle Build Scan

    This is so that you can see any deprecation warnings that apply to your build. Gradle 5.x will generate (potentially less obvious) errors if you try to upgrade directly to it.

    Alternatively, you could run gradle help --warning-mode=all to see the deprecations in the console, though it may not report as much detailed information.

  3. Update your plugins.

    Some plugins will break with this new version of Gradle, for example because they use internal APIs that have been removed or changed. The previous step will help you identify potential problems by issuing deprecation warnings when a plugin does try to use a deprecated part of the API.

    In particular, you will need to use at least a 2.x version of the Shadow Plugin.

  4. Run gradle wrapper --gradle-version 5.0 to update the project to 5.0

  5. Move to Java 8 or higher if you haven’t already. Whereas Gradle 4.x requires Java 7, Gradle 5 requires Java 8 to run.

  6. Read the Upgrading from 4.10 section and make any necessary changes.

  7. Try to run the project and debug any errors using the Troubleshooting Guide.

In addition, Gradle has added several significant new and improved features that you should consider using in your builds:

Other notable changes to be aware of that may break your build include:

Upgrading from 4.10 and earlier

If you are not already on version 4.10, skip down to the section that applies to your current Gradle version and work your way up until you reach here.

Other changes

  • The enableFeaturePreview('IMPROVED_POM_SUPPORT') and enableFeaturePreview('STABLE_PUBLISHING') flags are no longer necessary. These features are now enabled by default.

  • Gradle now bundles JAXB for Java 9 and above. You can remove the --add-modules java.xml.bind option from org.gradle.jvmargs, if set.

Potential breaking changes

The changes in this section have the potential to break your build, but the vast majority have been deprecated for quite some time and few builds will be affected by a large number of them. We strongly recommend upgrading to Gradle 4.10 first to get a report on what deprecations affect your build.

The following breaking changes are not from deprecations, but the result of changes in behavior:

  • Separation of compile and runtime dependencies when consuming POMs

  • The evaluation of the publishing {} block is no longer deferred until needed but behaves like any other block. Please use afterEvaluate {} if you need to defer evaluation.

  • The Javadoc and Groovydoc tasks now delete the destination dir for the documentation before executing. This has been added to remove stale output files from the last task execution.

  • The Java Library Distribution Plugin is now based on the Java Library Plugin instead of the Java Plugin.

    While it applies the Java Plugin, it behaves slightly different (e.g. it adds the api configuration). Thus, make sure to check whether your build behaves as expected after upgrading.

  • The html property on CheckstyleReport and FindBugsReport now returns a CustomizableHtmlReport instance that is easier to configure from statically typed languages like Java and Kotlin.

  • The Configuration Avoidance API has been updated to prevent the creation and configuration of tasks that are never used.

The following breaking changes will appear as deprecation warnings with Gradle 4.10:

General
  • << for task definitions no longer works. In other words, you can not use the syntax task myTask << { …​ }.

    Use the Task.doLast() method instead, like this:

    task myTask {
        doLast {
            ...
        }
    }
  • You can no longer use any of the following characters in domain object names, such as project and task names: <space> / \ : < > " ? * | . You should also not use . as a leading or trailing character.

Running Gradle & build environment
  • As mentioned before, Gradle can no longer be run on Java 7. However, you can still use forked compilation and testing to build and test software for Java 6 and above.

  • The -Dtest.single command-line option has been removed — use test filtering instead.

  • The -Dtest.debug command-line option has been removed — use the --debug-jvm option instead.

  • The -u/--no-search-upward command-line option has been removed — make sure all your builds have a settings.gradle file.

  • The --recompile-scripts command-line option has been removed.

  • You can no longer have a Gradle build nested in a subdirectory of another Gradle build unless the nested build has a settings.gradle file.

  • The DirectoryBuildCache.setTargetSizeInMB(long) method has been removed — use DirectoryBuildCache.removeUnusedEntriesAfterDays instead.

  • The org.gradle.readLoggingConfigFile system property no longer does anything — update affected tests to work with your java.util.logging settings.

Working with files
  • You can no longer cast FileCollection objects to other types using the as keyword or the asType() method.

  • You can no longer pass null as the configuration action of CopySpec.from(Object, Action).

  • For better compatibility with the Kotlin DSL, CopySpec.duplicatesStrategy is no longer nullable. The property setter no longer accepts null as a way to reset the property back to its default value. Use DuplicatesStrategy.INHERIT instead.

  • The FileCollection.stopExecutionIfEmpty() method has been removed — use the @SkipWhenEmpty annotation on FileCollection task properties instead.

  • The FileCollection.add() method has been removed — use Project.files() and Project.fileTree() to create configurable file collections/file trees and add to them via ConfigurableFileCollection.from().

  • SimpleFileCollection has been removed — use Project.files(Object…​) instead.

  • Don’t have your own classes extend AbstractFileCollection — use the Project.files() method instead. This problem may exhibit as a missing getBuildDependencies() method.

Java builds
Tasks & properties
  • The following legacy classes and methods related to lazy properties have been removed — use ObjectFactory.property() to create Property instances:

    • PropertyState

    • DirectoryVar

    • RegularFileVar

    • ProjectLayout.newDirectoryVar()

    • ProjectLayout.newFileVar()

    • Project.property(Class)

    • Script.property(Class)

    • ProviderFactory.property(Class)

  • Tasks configured and registered with the task configuration avoidance APIs have more restrictions on the other methods that can be called from a configuration action.

  • The internal @Option and @OptionValues annotations — package org.gradle.api.internal.tasks.options — have been removed. Use the public @Option and @OptionValues annotations instead.

  • The Task.deleteAllActions() method has been removed with no replacement.

  • The Task.dependsOnTaskDidWork() method has been removed — use declared inputs and outputs instead.

  • The following properties and methods of TaskInternal have been removed — use task dependencies, task rules, reusable utility methods, or the Worker API in place of executing a task directly.

    • execute()

    • executer

    • getValidators()

    • addValidator()

  • The TaskInputs.file(Object) method can no longer be called with an argument that resolves to anything other than a single regular file.

  • The TaskInputs.dir(Object) method can no longer be called with an argument that resolves to anything other than a single directory.

  • You can no longer register invalid inputs and outputs via TaskInputs and TaskOutputs.

  • The TaskDestroyables.file() and TaskDestroyables.files() methods have been removed — use TaskDestroyables.register() instead.

  • SimpleWorkResult has been removed — use WorkResult.didWork.

  • Overriding built-in tasks deprecated in 4.8 now produces an error.

    Attempting to replace a built-in task will produce an error similar to the following:

    > Cannot add task 'wrapper' as a task with that name already exists.
Scala & Play
  • Play 2.2 is no longer supported — please upgrade the version of Play you are using.

  • The ScalaDocOptions.styleSheet property has been removed — the Scaladoc Ant task in Scala 2.11.8 and later no longer supports this property.

Kotlin DSL
  • Artifact configuration accessors now have the type NamedDomainObjectProvider<Configuration> instead of Configuration

  • PluginAware.apply<T>(to) was renamed PluginAware.applyTo<T>(target).

Both changes could cause script compilation errors. See the Gradle Kotlin DSL release notes for more information and how to fix builds broken by the changes described above.

Miscellaneous
  • The ConfigurableReport.setDestination(Object) method has been removed — use ConfigurableReport.setDestination(File) instead.

  • The Signature.setFile(File) method has been removed — Gradle does not support changing the output file for the generated signature.

  • The read-only Signature.toSignArtifact property has been removed — it should never have been part of the public API.

  • The @DeferredConfigurable annotation has been removed.

  • The method isDeferredConfigurable() was removed from ExtensionSchema.

  • IdeaPlugin.performPostEvaluationActions() and EclipsePlugin.performPostEvaluationActions() have been removed.

  • The `BroadcastingCollectionEventRegister.getAddAction() method has been removed with no replacement.

  • The internal org.gradle.util package is no longer imported by default.

    Ideally you shouldn’t use classes from this package, but, as a quick fix, you can add explicit imports to your build scripts for those classes.

  • The gradlePluginPortal() repository no longer looks for JARs without a POM by default.

  • The Tooling API can no longer connect to builds using a Gradle version below Gradle 2.6. The same applies to builds run through TestKit.

  • Gradle 5.0 requires a minimum Tooling API client version of 3.0. Older client libraries can no longer run builds with Gradle 5.0.

  • The IdeaModule Tooling API model element contains methods to retrieve resources and test resources so those elements were removed from the result of IdeaModule.getSourceDirs() and IdeaModule.getTestSourceDirs().

  • In previous Gradle versions, the source field in SourceTask was accessible from subclasses. This is not the case anymore as the source field is now declared as private.

  • In the Worker API, the working directory of a worker can no longer be set.

  • A change in behavior related to dependency and version constraints may impact a small number of users.

  • There have been several changes to property factory methods on DefaultTask that may impact the creation of custom tasks.

Upgrading from 4.9 and earlier

Deprecated classes, methods and properties

Follow the API links to learn how to deal with these deprecations (if no extra information is provided here):

Potential breaking changes

Upgrading from 4.8 and earlier

Potential breaking changes

Upgrading from 4.7 and earlier

Potential breaking changes

  • Build will now fail if a specified init script is not found.

  • TaskContainer.remove() now actually removes the given task — some plugins may have accidentally relied on the old behavior.

  • Gradle now honors implicit wildcards in Maven POM exclusions.

  • The Kotlin DSL now respects JSR-305 package annotations.

    This will lead to some types annotated according to JSR-305 being treated as nullable where they were treated as non-nullable before. This may lead to compilation errors in the build script. See the relevant Kotlin DSL release notes for details.

  • Error messages will be directed to standard error rather than standard output now, unless a console is attached to both standard output and standard error. This may affect tools that scrape a build’s plain console output. Ignore this change if you’re upgrading from an earlier version of Gradle.

Deprecations

Prior to this release, builds were allowed to replace built-in tasks. This feature has been deprecated(https://docs.gradle.org/4.8/release-notes.html#overwriting-gradle’s-built-in-tasks).

The full list of built-in tasks that should not be replaced is: wrapper, init, help, tasks, projects, buildEnvironment, components, dependencies, dependencyInsight, dependentComponents, model, properties.

Upgrading from 4.6 and earlier

Potential breaking changes

  • Gradle will now, by convention, look for Checkstyle configuration files in the root project’s config/checkstyle directory.

    Checkstyle configuration files in subprojects — the old by-convention location — will be ignored unless you explicitly configure their path via checkstyle.configDir or checkstyle.config.

  • The structure of Gradle’s plain console output has changed, which may break tools that scrape that output.

  • The APIs of many native tasks related to compilation, linking and installation have changed in breaking ways.

  • [Kotlin DSL] Delegated properties used to access Gradle’s build properties — defined in gradle.properties for example — must now be explicitly typed.

  • [Kotlin DSL] Declaring a plugins {} block inside a nested scope now throws an exception.

  • [Kotlin DSL] Only one pluginManagement {} block is allowed now.

  • The cache control DSL provided by the org.gradle.api.artifacts.cache.* interfaces are no longer available.

  • getEnabledDirectoryReportDestinations(), getEnabledFileReportDestinations() and getEnabledReportNames() have all been removed from org.gradle.api.reporting.ReportContainer.

  • StartParameter.projectProperties and StartParameter.systemPropertiesArgs now return immutable maps.

Upgrading from 4.5 and earlier

Deprecations

  • You should not put annotation processors on the compile classpath or declare them with the -processorpath compiler argument.

    They 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 a library you depend on), use the -proc:none compiler argument to ignore it.

  • Use CommandLineArgumentProvider in place of CompilerArgumentProvider.

Potential breaking changes

  • The Java plugins now add a sourceSetAnnotationProcessor configuration for each source set, which might break if any of them match existing configurations you have. We recommend you remove your conflicting configuration declarations.

  • The StartParameter.taskOutputCacheEnabled property has been replaced by StartParameter.setBuildCacheEnabled(boolean).

  • The Visual Studio integration now only configures a single solution for all components in a build.

  • Gradle has replaced HttpClient 4.4.1 with version 4.5.5.

  • Gradle now bundles the kotlin-stdlib-jdk8 artifact instead of kotlin-stdlib-jre8. This may affect your build. Please see the Kotlin documentation for more details.

Upgrading from 4.4 and earlier

  • Make sure you have a settings.gradle file: it avoids a performance penalty and allows you to set the root project’s name.

  • Gradle now ignores the build cache configuration of included builds (composite builds) and instead uses the root build’s configuration for all the builds.

Potential breaking changes

  • Two overloaded ValidateTaskProperties.setOutputFile() methods were removed. They are replaced with auto-generated setters when the task is accessed from a build script, but that won’t be the case from plugins and other code outside of the build script.

  • The Maven Publish Plugin now produces more complete maven-metadata.xml files, including maintaining a list of <snapshotVersion> elements. Some older versions of Maven may not be able to consume this metadata.

  • HttpBuildCache no longer follows redirects.

  • The Depend task type has been removed.

  • Project.file(Object) no longer normalizes case for file paths on case-insensitive file systems. It now ignores case in such circumstances and does not touch the file system.

  • ListProperty no longer extends Property.

Upgrading from 4.3 and earlier

Potential breaking changes

  • AbstractTestTask is now extended by non-JVM test tasks as well as Test. Plugins should beware configuring all tasks of type AbstractTestTask because of this.

  • The default output location for EclipseClasspath.defaultOutputDir has changed from $projectDir/bin to $projectDir/bin/default.

  • The deprecated InstallExecutable.setDestinationDir(Provider) was removed — use InstallExecutable.installDirectory instead.

  • The deprecated InstallExecutable.setExecutable(Provider) was removed — use InstallExecutable.executableFile instead.

  • Gradle will no longer prefer a version of Visual Studio found on the path over other locations. It is now a last resort.

    You can bypass the toolchain discovery by specifying the installation directory of the version of Visual Studio you want via VisualCpp.setInstallDir(Object).

  • pluginManagement.repositories is now of type RepositoryHandler rather than PluginRepositoriesSpec, which has been removed.

  • 5xx HTTP errors during dependency resolution will now trigger exceptions in the build.

  • The embedded Apache Ant has been upgraded from 1.9.6 to 1.9.9.

  • Several third-party libraries used by Gradle have been upgraded to fix security issues.

Upgrading from 4.2 and earlier

Other deprecations

Potential breaking changes

  • DefaultTask.newOutputDirectory() now returns a DirectoryProperty instead of a DirectoryVar.

  • DefaultTask.newOutputFile() now returns a RegularFileProperty instead of a RegularFileVar.

  • DefaultTask.newInputFile() now returns a RegularFileProperty instead of a RegularFileVar.

  • ProjectLayout.buildDirectory now returns a DirectoryProperty instead of a DirectoryVar.

  • AbstractNativeCompileTask.compilerArgs is now of type ListProperty<String> instead of List<String>.

  • AbstractNativeCompileTask.objectFileDir is now of type DirectoryProperty instead of File.

  • AbstractLinkTask.linkerArgs is now of type ListProperty<String> instead of List<String>.

  • TaskDestroyables.getFiles() is no longer part of the public API.

  • Overlapping version ranges for a dependency now result in Gradle picking a version that satisfies all declared ranges.

    For example, if a dependency on some-module is found with a version range of [3,6] and also transitively with a range of [4,8], Gradle now selects version 6 instead of 8. The prior behavior was to select 8.

  • The order of elements in Iterable properties marked with either @OutputFiles or @OutputDirectories now matters. If the order changes, the property is no longer considered up to date.

    Prefer using separate properties with @OutputFile/@OutputDirectory annotations or use Map properties with @OutputFiles/@OutputDirectories instead.

  • Gradle will no longer ignore dependency resolution errors from a repository when there is another repository it can check. Dependency resolution will fail instead. This results in more deterministic behavior with respect to resolution results.

Upgrading from 4.1 and earlier

Potential breaking changes

Upgrading from 4.0

  • Consider using the new Worker API to enable units of work within your build to run in parallel.

Deprecated classes, methods and properties

Follow the API links to learn how to deal with these deprecations (if no extra information is provided here):

Potential breaking changes

  • Non-Java projects that have a project dependency on a Java project now consume the runtimeElements configuration by default instead of the default configuration.

    To override this behavior, you can explicitly declare the configuration to use in the project dependency. For example: project(path: ':myJavaProject', configuration: 'default').

  • Default Zinc compiler upgraded from 0.3.13 to 0.3.15.

  • [Kotlin DSL] Base package renamed from org.gradle.script.lang.kotlin to org.gradle.kotlin.dsl.

Changes in detail

[5.0] Default memory settings changed

The command line client now starts with 64MB of heap instead of 1GB. This may affect builds running directly inside the client VM using --no-daemon mode. We discourage the use of --no-daemon, but if you must use it, you can increase the available memory using the GRADLE_OPTS environment variable.

The Gradle daemon now starts with 512MB of heap instead of 1GB. Large projects may have to increase this setting using the org.gradle.jvmargs property.

All workers, including compilers and test executors, now start with 512MB of heap. The previous default was 1/4th of physical memory. Large projects may have to increase this setting on the relevant tasks, e.g. JavaCompile or Test.

[5.0] New default versions for code quality plugins

The default tool versions of the following code quality plugins have been updated:

  • The Checkstyle Plugin now uses 8.12 instead of 6.19 by default.

  • The CodeNarc Plugin now uses 1.2.1 instead of 1.1 by default.

  • The JaCoCo Plugin now uses 0.8.2 instead of 0.8.1 by default.

  • The PMD Plugin now uses 6.8.0 instead of 5.6.1 by default.

    In addition, the default ruleset was changed from the now deprecated java-basic to category/java/errorprone.xml.

    We recommend configuring a ruleset explicitly, though.

[5.0] Library upgrades

Several libraries that are used by Gradle have been upgraded:

  • Groovy was upgraded from 2.4.15 to 2.5.4.

  • Ant has been upgraded from 1.9.11 to 1.9.13.

  • The AWS SDK used to access S3-backed Maven/Ivy repositories has been upgraded from 1.11.267 to 1.11.407.

  • The BND library used by the OSGi Plugin has been upgraded from 3.4.0 to 4.0.0.

  • The Google Cloud Storage JSON API Client Library used to access Google Cloud Storage backed Maven/Ivy repositories has been upgraded from v1-rev116-1.23.0 to v1-rev136-1.25.0.

  • Ivy has been upgraded from 2.2.0 to 2.3.0.

  • The JUnit Platform libraries used by the Test task have been upgraded from 1.0.3 to 1.3.1.

  • The Maven Wagon libraries used to access Maven repositories have been upgraded from 2.4 to 3.0.0.

  • SLF4J has been upgraded from 1.7.16 to 1.7.25.

[5.0] Improved support for dependency and version constraints

Through the Gradle 4.x release stream, new @Incubating features were added to the dependency resolution engine. These include sophisticated version constraints (prefer, strictly, reject), dependency constraints, and platform dependencies.

If you have been using the IMPROVED_POM_SUPPORT feature preview, playing with constraints or prefer, reject and other specific version indications, then make sure to take a good look at your dependency resolution results.

[5.0] BOM import

Gradle now provides support for importing bill of materials (BOM) files, which are effectively POM files that use <dependencyManagement> sections to control the versions of direct and transitive dependencies. All you need to do is declare the POM as a platform dependency.

The following example picks the versions of the gson and dom4j dependencies from the declared Spring Boot BOM:

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

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

[5.0] Separation of compile and runtime dependencies when consuming POMs

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

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

  • The compilation classpath includes runtime-scoped files that do not impact compilation, resulting in unnecessary re-compilation when those files change.

With this new behavior, the Java and Java Library plugins both honor the separation of compile and runtime scopes. This means that the compilation classpath only includes compile-scoped dependencies, while the runtime classpath adds the runtime-scoped dependencies as well. This is particularly useful if you develop and publish Java libraries with Gradle where the separation between api and implementation dependencies is reflected in the published scopes.

[5.0] Changes to property factory methods on DefaultTask

Property factory methods on DefaultTask are now final

The property factory methods such as newInputFile() are intended to be called from the constructor of a type that extends DefaultTask. These methods are now final to avoid subclasses overriding these methods and using state that is not initialized.

Inputs and outputs are not automatically registered

The Property instances that are returned by these methods are no longer automatically registered as inputs or outputs of the task. The Property instances need to be declared as inputs or outputs in the usual ways, such as attaching annotations such as @OutputFile or using the runtime API to register the property.

For example, you could previously use the following syntax and have both outputFile instances registered as declared outputs:

build.gradle
class MyTask extends DefaultTask {
    // note: no annotation here
    final RegularFileProperty outputFile = newOutputFile()
}

task myOtherTask {
    def outputFile = newOutputFile()
    doLast { ... }
}
build.gradle.kts
open class MyTask : DefaultTask() {
    // note: no annotation here
    val outputFile: RegularFileProperty = newOutputFile()
}

task("myOtherTask") {
    val outputFile = newOutputFile()
    doLast { ... }
}

Now you have to explicitly register outputFile, like this:

build.gradle
class MyTask extends DefaultTask {
    @OutputFile // property needs an annotation
    final RegularFileProperty outputFile = project.objects.fileProperty()
}

task myOtherTask {
    def outputFile = project.objects.fileProperty()
    outputs.file(outputFile) // or to be registered using the runtime API
    doLast { ... }
}
build.gradle.kts
open class MyTask : DefaultTask() {
    @OutputFile // property needs an annotation
    val outputFile: RegularFileProperty = project.objects.fileProperty()
}

task("myOtherTask") {
    val outputFile = project.objects.fileProperty()
    outputs.file(outputFile) // or to be registered using the runtime API
    doLast { ... }
}

[5.0] Gradle now bundles JAXB for Java 9 and above

In order to use S3 backed artifact repositories, you previously had to add --add-modules java.xml.bind to org.gradle.jvmargs when running on Java 9 and above.

Since Java 11 no longer contains the java.xml.bind module, Gradle now bundles JAXB 2.3.1 (com.sun.xml.bind:jaxb-impl) and uses it on Java 9 and above.

Please remove the --add-modules java.xml.bind option from org.gradle.jvmargs, if set.

[5.0] The gradlePluginPortal() repository no longer looks for JARs without a POM by default

With this new behavior, if a plugin or a transitive dependency of a plugin found in the gradlePluginPortal() repository has no Maven POM it will fail to resolve.

Artifacts published to a Maven repository without a POM should be fixed. If you encounter such artifacts, please ask the plugin or library author to publish a new version with proper metadata.

If you are stuck with a bad plugin, you can work around by re-enabling JARs as metadata source for the gradlePluginPortal() repository:

settings.gradle
pluginManagement {
    repositories {
        gradlePluginPortal().tap {
            metadataSources {
                mavenPom()
                artifact()
            }
        }
    }
}
settings.gradle.kts
pluginManagement {
    repositories {
        gradlePluginPortal().apply {
            (this as MavenArtifactRepository).metadataSources {
                mavenPom()
                artifact()
            }
        }
    }
}

Java Library Distribution Plugin utilizes Java Library Plugin

The Java Library Distribution Plugin is now based on the Java Library Plugin instead of the Java Plugin.

Additionally, the default distribution created by the plugin will contain all artifacts of the runtimeClasspath configuration instead of the deprecated runtime configuration.

Configuration Avoidance API disallows common configuration errors

The configuration avoidance API introduced in Gradle 4.9 allows you to avoid creating and configuring tasks that are never used.

With the existing API, this example adds two tasks (foo and bar):

build.gradle
tasks.create("foo") {
    tasks.create("bar")
}
build.gradle.kts
tasks.create("foo") {
    tasks.create("bar")
}

When converting this to use the new API, something surprising happens: bar doesn’t exist. The new API only executes configuration actions when necessary, so the register() for task bar only executes when foo is configured.

build.gradle
tasks.register("foo") {
    tasks.register("bar") // WRONG
}
build.gradle.kts
tasks.register("foo") {
    tasks.register("bar") // WRONG
}

To avoid this, Gradle now detects this and prevents modification to the underlying container (through create() or register()) when using the new API.

[5.0] Worker API: working directory of a worker can no longer be set

Since JDK 11 no longer supports changing the working directory of a running process, setting the working directory of a worker via its fork options is now prohibited.

All workers now use the same working directory to enable reuse.

Please pass files and directories as arguments instead.

[4.10] Publishing to AWS S3 requires new permissions

The S3 repository transport protocol allows Gradle to publish artifacts to AWS S3 buckets. Starting with this release, every artifact uploaded to an S3 bucket will be equipped with the bucket-owner-full-control canned ACL. Make sure that the AWS account used to publish artifacts has the s3:PutObjectAcl and s3:PutObjectVersionAcl permissions, otherwise the upload will fail.

{
    "Version":"2012-10-17",
    "Statement":[
        // ...
        {
            "Effect":"Allow",
            "Action":[
                "s3:PutObject", // necessary for uploading objects
                "s3:PutObjectAcl", // required starting with this release
                "s3:PutObjectVersionAcl" // if S3 bucket versioning is enabled
            ],
            "Resource":"arn:aws:s3:::myCompanyBucket/*"
        }
    ]
}

See AWS S3 Cross Account Access for more information.

[4.9] Consider trying the lazy API for task creation and configuration

Gradle 4.9 introduced a new way to create and configure tasks that works lazily. When you use this approach for tasks that are expensive to configure, or when you have many, many tasks, your build configuration time can drop significantly when those tasks don’t run.

You can learn more about lazily creating tasks in the Task Configuration Avoidance chapter. You can also read about the background to this new feature in this blog post.

[4.8] Switch to the Maven Publish and Ivy Publish Plugins

Now that the publishing plugins are stable, we recommend that you migrate from the legacy publishing mechanism for standard Java projects, i.e. those based on the Java Plugin. That includes projects that use any one of: Java Library Plugin, Application Plugin or War Plugin.

To use the new approach, simply replace any upload<Conf> configuration with a publishing {} block. See the publishing overview chapter for more information.

[4.8] Use deferred configuration for publishing plugins

Prior to Gradle 4.8, the publishing {} block was implicitly treated as if all the logic inside it was executed after the project was evaluated. This was confusing, 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.

The new, stable behavior can be switched on by adding the following to your settings file:

settings.gradle
enableFeaturePreview('STABLE_PUBLISHING')
settings.gradle.kts
enableFeaturePreview("STABLE_PUBLISHING")

We recommend doing a test run with a local repository to see whether all artifacts still have the expected coordinates. In most cases everything should work as before and you are done. However, your publishing block may rely on the implicit deferred configuration, particularly if it relies on values that may change during the configuration phase of the build.

For example, under the new behavior, the following logic assumes that jar.baseName doesn’t change after artifactId is set:

build.gradle
subprojects {
    publishing {
        publications {
            mavenJava {
                from components.java
                artifactId = jar.baseName
            }
        }
    }
}
build.gradle.kts
subprojects {
    publishing {
        publications {
            named<MavenPublication>("mavenJava") {
                from(components["java"])
                artifactId = tasks.jar.get().baseName
            }
        }
    }
}

If that assumption is incorrect or might possibly be incorrect in the future, the artifactId must be set within an afterEvaluate {} block, like so:

build.gradle
subprojects {
    publishing {
        publications {
            mavenJava {
                from components.java
                afterEvaluate {
                    artifactId = jar.baseName
                }
            }
        }
    }
}
build.gradle.kts
subprojects {
    publishing {
        publications {
            named<MavenPublication>("mavenJava") {
                from(components["java"])
                afterEvaluate {
                    artifactId = tasks.jar.get().baseName
                }
            }
        }
    }
}

[4.8] Configure existing wrapper and init tasks

You should no longer define your own wrapper and init tasks. Configure the existing tasks instead, for example by converting this:

build.gradle
task wrapper(type: Wrapper) {
    ...
}
build.gradle.kts
task<Wrapper>("wrapper") {
    ...
}

to this:

build.gradle
wrapper {
    ...
}
build.gradle.kts
tasks.wrapper {
    ...
}

[4.8] Gradle now honors implicit wildcards in Maven POM exclusions

If an exclusion in a Maven POM was missing either a groupId or artifactId, Gradle used to ignore the exclusion. Now the missing elements are treated as implicit wildcards — e.g. <groupId>*</groupId> — which means that some of your dependencies may now be excluded where they weren’t before.

You will need to explicitly declare any missing dependencies that you need.

[4.7] Changes to the structure of Gradle’s plain console output

The plain console mode now formats output consistently with the rich console, which means that the output format has changed. For example:

  • The output produced by a given task is now grouped together, even when other tasks execute in parallel with it.

  • Task execution headers are printed with a "> Task" prefix.

  • All output produced during build execution is written to the standard output file handle. This includes messages written to System.err unless you are redirecting standard error to a file or any other non-console destination.

This may break tools that scrape details from the plain console output.

[4.6] Changes to the APIs of native tasks related to compilation, linking and installation

Many tasks related to compiling, linking and installing native libraries and applications have been converted to the Provider API so that they support lazy configuration. This conversion has introduced some breaking changes to the APIs of the tasks so that they match the conventions of the Provider API.

The following tasks have been changed:

AbstractLinkTask and its subclasses
  • getDestinationDir() was replaced by getDestinationDirectory().

  • getBinaryFile(), getOutputFile() was replaced by getLinkedFile().

  • setOutputFile(File) was removed. Use Property.set() instead.

  • setOutputFile(Provider) was removed. Use Property.set() instead.

  • getTargetPlatform() was changed to return a Property.

  • setTargetPlatform(NativePlatform) was removed. Use Property.set() instead.

  • getToolChain() was changed to return a Property.

  • setToolChain(NativeToolChain) was removed. Use Property.set() instead.

CreateStaticLibrary
  • getOutputFile() was changed to return a Property.

  • setOutputFile(File) was removed. Use Property.set() instead.

  • setOutputFile(Provider) was removed. Use Property.set() instead.

  • getTargetPlatform() was changed to return a Property.

  • setTargetPlatform(NativePlatform) was removed. Use Property.set() instead.

  • getToolChain() was changed to return a Property.

  • setToolChain(NativeToolChain) was removed. Use Property.set() instead.

  • getStaticLibArgs() was changed to return a ListProperty.

  • setStaticLibArgs(List) was removed. Use ListProperty.set() instead.

InstallExecutable
  • getSourceFile() was replaced by getExecutableFile().

  • getPlatform() was replaced by getTargetPlatform().

  • setTargetPlatform(NativePlatform) was removed. Use Property.set() instead.

  • getToolChain() was changed to return a Property.

  • setToolChain(NativeToolChain) was removed. Use Property.set() instead.

The following have also seen similar changes:

[4.6] Visual Studio integration only supports a single solution file for all components of a build

VisualStudioExtension no longer has a solutions property. Instead, you configure a single solution via VisualStudioRootExtension in the root project, like so:

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

In addition, there are no longer individual tasks to generate the solution files for each component, but rather a single visualStudio task that generates a solution file that encompasses all components in the build.

[4.5] HttpBuildCache no longer follows redirects

When connecting to an HTTP build cache backend via HttpBuildCache, Gradle does not follow redirects any more, treating them as errors instead. Getting a redirect from the build cache backend is mostly a configuration error — using an "http" URL instead of "https" for example — and has negative effects on performance.

[4.4] Third-party dependency upgrades

This version includes several upgrades of third-party dependencies:

  • jackson: 2.6.6 → 2.8.9

  • plexus-utils: 2.0.6 → 2.1

  • xercesImpl: 2.9.1 → 2.11.0

  • bsh: 2.0b4 → 2.0b6

  • bouncycastle: 1.57 → 1.58

This fix the following security issues:

Gradle does not expose public APIs for these 3rd-party dependencies, but those who customize Gradle will want to be aware.