# Upgrading your build from Gradle 6.x to the latest

version 6.8

This chapter provides the information you need to migrate your Gradle 6.x builds to the latest Gradle release. For migrating from Gradle 4.x or 5.x, see the older migration guide first.

We recommend the following steps for all users:

1. Try running `gradle help --scan` and view the deprecations view of the generated build scan.

   This is so that you can see any deprecation warnings that apply to your build.

   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.

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

3. Run `gradle wrapper --gradle-version 6.8` to update the project to 6.8.

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

## Upgrading from 6.7

### Potential breaking changes

#### Toolchain API is now marked as @NonNull

The API supporting the Java Toolchain feature in `org.gradle.jvm.toolchain` is now marked as `@NonNull`.

This may impact Kotlin consumers where the return types of APIs are no longer nullable.

#### Updates to default tool integration versions

- JaCoCo has been updated to 0.8.6.

- Checkstyle has been updated to Checkstyle 8.37.

- CodeNarc has been updated to CodeNarc 2.0.0.

#### Updates to bundled Gradle dependencies

- Kotlin has been updated to Kotlin 1.4.20. Note that Gradle scripts are still using the Kotlin 1.3 language.

- Apache Ant has been updated to 1.10.9 to fix CVE-2020-11979

#### Projects imported into Eclipse now include custom source set classpaths

Previously, projects imported by Eclipse only included dependencies for the main and test source sets. The compile and runtime classpaths of custom source sets were ignored.

Since Gradle 6.8, projects imported into Eclipse include the compile and runtime classpath for every source set defined by the build.

#### SourceTask is no longer sensitive to empty directories

Previously, empty directories would be taken into account during up-to-date checks and build cache key calculations for the sources declared in `SourceTask`. This meant that a source tree that contained an empty directory and an otherwise identical source tree that did not contain the empty directory would be considered different sources, even if the task would produce the same outputs. In Gradle 6.8, `SourceTask` now ignores empty directories during doing up-to-date checks and build cache key calculations. In the vast majority of cases, this is the desired behavior, but it is possible that a task may extend `SourceTask` but also produce different outputs when empty directories are present in the sources. For tasks where this is a concern, you can expose a separate property without the `@IgnoreEmptyDirectories` annotation in order to capture those changes:

    @InputFiles
    @SkipWhenEmpty
    @PathSensitive(PathSensitivity.ABSOLUTE)
    public FileTree getSourcesWithEmptyDirectories() {
        return super.getSource()
    }

### Deprecations

#### Referencing tasks from included builds

Direct references to tasks from included builds in `mustRunAfter`, `shouldRunAfter` and `finalizedBy` task methods have been deprecated. Task ordering using `mustRunAfter` and `shouldRunAfter` as well as finalizers specified by `finalizedBy` should be used for task ordering within a build. If you happen to have cross-build task ordering defined using above mentioned methods, consider restructuring such builds and decoupling them from one another.

#### Searching for settings files in 'master' directories

Gradle will emit a deprecation warning when your build relies on finding the settings file in a directory named `master` in a sibling directory.

If your build uses this feature, consider refactoring the build to have the root directory match the physical root of the project hierarchy.

Alternatively, you can still run tasks in builds like this by invoking the build from the `master` directory only using a fully qualified path to the task.

#### Using method `NamedDomainObjectContainer<T>.invoke(kotlin.Function1)`

Gradle Kotlin DSL extensions have been changed to favor Gradle’s `Action<T>` type over Kotlin function types.

While the change should be transparent to Kotlin clients, Java clients calling Kotlin DSL extensions need to be updated to use the `Action<T>` APIs.

## Upgrading from 6.6

### Potential breaking changes

#### buildSrc can now see included builds from the root

Previously, `buildSrc` was built in such a way that included builds were ignored from the root build.

Since Gradle 6.7, `buildSrc` can see any included build from the root build. This may cause dependencies to be substituted from an included build in `buildSrc`. This may also change the order in which some builds are executed if an included build is needed by `buildSrc`.

#### Updates to default tool integration versions

- PMD has been updated to PMD 6.26.0.

- Checkstyle has been updated to Checkstyle 8.35.

- CodeNarc has been updated to CodeNarc 1.6.1.

### Deprecations

#### Changing default excludes during the execution phase

Gradle’s file trees apply some default exclude patterns for convenience — the same defaults as Ant in fact. See the user manual for more information. Sometimes, Ant’s default excludes prove problematic, for example when you want to include the `.gitignore` in an archive file.

Changing Gradle’s default excludes during the execution phase can lead to correctness problems with up-to-date checks, and is deprecated. You are only allowed to change Gradle’s default excludes in the settings script, see the user manual for an example.

#### Using a Configuration directly as a dependency

Gradle allowed instances of `Configuration` to be used directly as dependencies:

    dependencies {
        implementation(configurations.myConfiguration)
    }

This behavior is now deprecated as it is confusing: one could expect the "dependent configuration" to be resolved first and add the result of resolution as dependencies to the including configuration, which is not the case. The deprecated version can be replaced with the actual behavior, which is configuration inheritance:

    configurations.implementation.extendsFrom(configurations.myConfiguration)

## Upgrading from 6.5

### Potential breaking changes

#### Updates to bundled Gradle dependencies

- Ant has been updated to 1.10.8.

- Groovy has been updated to Groovy 2.5.12.

#### Dependency substitutions and variant aware dependency resolution

While adding support for expressing variant support in dependency substitutions, a bug fix introduced a behaviour change that some builds may rely upon. Previously a substituted dependency would still use the attributes of the original selector instead of the ones from the replacement selector.

With that change, existing substitutions around dependencies with richer selectors, such as for platform dependencies, will no longer work as they did. It becomes mandatory to define the variant aware part in the target selector.

You can be affected by this change if you:

- have dependencies on platforms, like `implementation platform("org:platform:1.0")`

- or if you specify attributes on dependencies,

- and you use resolution rules on these dependencies.

See the documentation for resolving issues if you are impacted.

### Deprecations

No deprecations were made in Gradle 6.6.

## Upgrading from 6.4

### Potential breaking changes

#### Updates to bundled Gradle dependencies

- Kotlin has been updated to Kotlin 1.3.72.

- Groovy has been updated to Groovy 2.5.11.

#### Updates to default tool integration versions

- PMD has been updated to PMD 6.23.0.

### Deprecations

#### Internal class AbstractTask is deprecated

`AbstractTask` is an internal class which is visible on the public API, as a superclass of public type `DefaultTask`. `AbstractTask` will be removed in Gradle 7.0, and the following are deprecated in Gradle 6.5:

- Registering a task whose type is `AbstractTask` or `TaskInternal`. You can remove the task type from the task registration and Gradle will use `DefaultTask` instead.

- Registering a task whose type is a subclass of `AbstractTask` but not a subclass of `DefaultTask`. You can change the task type to extend `DefaultTask` instead.

- Using the class `AbstractTask` from plugin code or build scripts. You can change the code to use `DefaultTask` instead.

## Upgrading from 6.3

### Potential breaking changes

#### PMD plugin expects PMD 6.0.0 or higher by default

Gradle 6.4 enabled incremental analysis by default. Incremental analysis is only available in PMD 6.0.0 or higher. If you want to use an older PMD version, you need to disable incremental analysis:

    pmd {
        incrementalAnalysis = false
    }

#### Changes in dependency locking

With Gradle 6.4, the incubating API for dependency locking `LockMode` has changed. The value is now set via a `Property<LockMode>` instead of a direct setter. This means that the notation to set the value has to be updated for the Kotlin DSL:

    dependencyLocking {
        lockMode.set(LockMode.STRICT)
    }

Users of the Groovy DSL should not be impacted as the notation `lockMode = LockMode.STRICT` remains valid.

#### Java versions in published metadata

If a Java library is published with Gradle Module Metadata, the information which Java version it supports is encoded in the `org.gradle.jvm.version` attribute. By default, this attribute was set to what you configured in `java.targetCompatibility`. If that was not configured, it was set to the current Java version running Gradle. Changing the version of a particular compile task, e.g. `javaCompile.targetCompatibility` had no effect on that attribute, leading to wrong information if the attribute was not adjusted manually. This is now fixed and the attribute defaults to the setting of the compile task that is associated with the sources from which the published jar is built.

#### Ivy repositories with custom layouts

Gradle versions from 6.0 to 6.3.x included could generate bad Gradle Module Metadata when publishing on an Ivy repository which had a custom repository layout. Starting from 6.4, Gradle will no longer publish Gradle Module Metadata if it detects that you are using a custom repository layout.

#### New properties may shadow variables in build scripts

This release introduces some new properties —`mainClass`, `mainModule`, `modularity`— in different places. Since these are very generic names, there is a chance that you use one of them in your build scripts as variable name. A new property might then shadow one of your variables in an undesired way, leading to a build failure where the property is accessed instead of the local variable with the same name. You can fix it by renaming the corresponding variable in the build script.

Affected is configuration code inside the `application {}` and `java {}` configuration blocks, inside a java execution setup with `project.javaexec {}`, and inside various task configurations (`JavaExec`, `CreateStartScripts`, `JavaCompile`, `Test`, `Javadoc`).

#### Updates to bundled Gradle dependencies

- Kotlin has been updated to Kotlin 1.3.71.

### Deprecations

There were no deprecations between Gradle 6.3 and 6.4.

## Upgrading from 6.2

### Potential breaking changes

#### Fewer dependencies available in IDEA

Gradle no longer includes the annotation processor classpath as provided dependencies in IDEA. The dependencies IDEA sees at compile time are the same as what Gradle sees after resolving the compile classpath (configuration named `compileClasspath`). This prevents the leakage of annotation processor dependencies into the project’s code.

Before Gradle introduced incremental annotation processing support, IDEA required all annotation processors to be on the compilation classpath to be able to run annotation processing when compiling in IDEA. This is no longer necessary because Gradle has a separate annotation processor classpath. The dependencies for annotation processors are not added to an IDEA module’s classpath when a Gradle project with annotation processors is imported.

#### Updates to bundled Gradle dependencies

- Kotlin has been updated to Kotlin 1.3.70.

- Groovy has been updated to Groovy 2.5.10.

#### Updates to default tool integration versions

- PMD has been updated to PMD 6.21.0.

- CodeNarc has been updated to CodeNarc 1.5.

#### Rich console support removed for some 32-bit operating systems

Gradle 6.3 does not support the rich console for 32-bit Unix systems and for old FreeBSD versions (older than FreeBSD 10). Microsoft Windows 32-bit is unaffected.

Gradle will continue building projects on 32-bit systems but will no longer show the rich console.

### Deprecations

#### Using default and archives configurations

Almost every Gradle project has the default and archives configurations which are added by the base plugin. These configurations are no longer used in modern Gradle builds that use variant aware dependency management and the new publishing plugins.

While the configurations will stay in Gradle for backwards compatibility for now, using them to declare dependencies or to resolve dependencies is now deprecated.

Resolving these configurations was never an intended use case and only possible because in earlier Gradle versions every configuration was resolvable. For declaring dependencies, please use the configurations provided by the plugins you use, for example by the Java Library plugin.

## Upgrading from 6.1

### Potential breaking changes

#### Compile and runtime classpath now request library variants by default

A classpath in a JVM project now explicitly requests the `org.gradle.category=library` attribute. This leads to clearer error messages if a certain library cannot be used. For example, when the library does not support the required Java version. The practical effect is that now all platform dependencies have to be declared as such. Before, platform dependencies also worked, accidentally, when the `platform()` keyword was omitted for local platforms or platforms published with Gradle Module Metadata.

#### Properties from project root `gradle.properties` leaking into `buildSrc` and included builds

There was a regression in Gradle 6.2 and Gradle 6.2.1 that caused Gradle properties set in the project root `gradle.properties` file to leak into the `buildSrc` build and any builds included by the root.

This could cause your build to start failing if the `buildSrc` build or an included build suddenly found an unexpected or incompatible value for a property coming from the project root `gradle.properties` file.

The regression has been fixed in Gradle 6.2.2.

### Deprecations

There were no deprecations between Gradle 6.1 and 6.2.

## Upgrading from 6.0 and earlier

### Deprecations

#### Querying a mapped output property of a task before the task has completed

Querying the value of a mapped output property before the task has completed can cause strange build failures because it indicates stale or non-existent outputs may be used by mistake. This behavior is deprecated and will emit a deprecation warning. This will become an error in Gradle 7.0.

The following example demonstrates this problem where the Producer’s output file is parsed before the Producer executes:

    class Consumer extends DefaultTask {
        @Input
        final Property<Integer> threadPoolSize = ...
    }

    class Producer extends DefaultTask {
        @OutputFile
        final RegularFileProperty outputFile = ...
    }

    // threadPoolSize is read from the producer's outputFile
    consumer.threadPoolSize = producer.outputFile.map { it.text.toInteger() }

    // Emits deprecation warning
    println("thread pool size = " + consumer.threadPoolSize.get())

Querying the value of `consumer.threadPoolSize` will produce a deprecation warning if done prior to `producer` completing, as the output file has not yet been generated.

#### Discontinued methods

The following methods have been discontinued and should no longer be used. They will be removed in Gradle 7.0.

- `BasePluginConvention.setProject(ProjectInternal)`

- `BasePluginConvention.getProject()`

- `StartParameter.useEmptySettings()`

- `StartParameter.isUseEmptySettings()`

#### Alternative JVM plugins (a.k.a "Software Model")

A set of alternative plugins for Java and Scala development were introduced in Gradle 2.x as an experiment based on the "software model". These plugins are now deprecated and will eventually be removed. If you are still using one of these old plugins (`java-lang`, `scala-lang`, `jvm-component`, `jvm-resources`, `junit-test-suite`) please consult the documentation on Building Java & JVM projects to determine which of the stable JVM plugins are appropriate for your project.

### Potential breaking changes

#### `ProjectLayout` is no longer available to worker actions as a service

In Gradle 6.0, the `ProjectLayout` service was made available to worker actions via service injection. This service allowed for mutable state to leak into a worker action and introduced a way for dependencies to go undeclared in the worker action.

`ProjectLayout` has been removed from the available services. Worker actions that were using `ProjectLayout` should switch to injecting the `projectDirectory` or `buildDirectory` as a parameter instead.

#### Updates to bundled Gradle dependencies

- Kotlin has been updated to Kotlin 1.3.61.

#### Updates to default tool integration versions

- Checkstyle has been updated to Checkstyle 8.27.

- PMD has been updated to PMD 6.20.0.

#### Publishing Spring Boot applications

Starting from Gradle 6.2, Gradle performs a sanity check before uploading, to make sure you don’t upload stale files (files produced by another build). This introduces a problem with Spring Boot applications which are uploaded using the `components.java` component:

    Artifact my-application-0.0.1-SNAPSHOT.jar wasn't produced by this build.

This is caused by the fact that the main `jar` task is disabled by the Spring Boot application, and the component expects it to be present. Because the `bootJar` task uses the same file as the main `jar` task by default, previous releases of Gradle would either:

- publish a stale `bootJar` artifact

- or fail if the `bootJar` task hasn’t been called previously

A workaround is to tell Gradle what to upload. If you want to upload the `bootJar`, then you need to configure the outgoing configurations to do this:

    configurations {
       [apiElements, runtimeElements].each {
           it.outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }
           it.outgoing.artifact(bootJar)
       }
    }

Alternatively, you might want to re-enable the `jar` task, and add the `bootJar` with a different classifier.

    jar {
       enabled = true
    }

    bootJar {
       classifier = 'application'
    }