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

version 7.1

This chapter provides the information you need to migrate your Gradle 7.x builds to the latest Gradle release. For migrating from Gradle 4.x, 5.x, or 6.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 7.1` to update the project to 7.1.

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

## Upgrading from 7.0 and earlier

### Potential breaking changes

#### Updates to default tool integration versions

- JaCoCo has been updated to 0.8.7.

#### The `org.gradle.util` package is now a public API

Officially, the `org.gradle.util` package is not part of the public API. But, because this package name doesn’t contain the word `internal`, many Gradle plugins already consider as one. Gradle 7.1 addresses the situation and marks the package as public. The classes that were unintentionally exposed are either deprecated or removed, depending on their external usage.

The following classes are now officially recognized as public API: - `GradleVersion` - `Path` - `Configurable`

The following classes have known usages in external plugins and are now deprecated and set for removal in Gradle 8.0:

- `VersionNumber`

- `TextUtil`

- `WrapUtil`

- `RelativePathUtil`

- `DistributionLocator`

- `SingleMessageLogger`

The following classes have only internal usages and were moved from `org.gradle.util` to the `org.gradle.util.internal` package:

- `Resources`

- `RedirectStdOutAndErr`

- `Swapper`

- `StdInSwapper`

- `IncubationLogger`

- `RedirectStdIn`

- `MultithreadedTestRule`

- `DisconnectableInputStream`

- `BulkReadInputStream`

- `MockExecutor`

- `FailsWithMessage`

- `FailsWithMessageExtension`

- `TreeVisitor`

- `AntUtil`

- `JarUtil`

The last set of classes have no external or internal usages and therefore were deleted:

- `DiffUtil`

- `NoopChangeListener`

- `EnumWithClassBody`

- `AlwaysTrue`

- `ReflectionEqualsMatcher`

- `DynamicDelegate`

- `IncubationLogger`

- `NoOpChangeListener`

- `DeferredUtil`

- `ChangeListener`

#### The return type of source set extensions have changed

The following source sets are contributed via an extension with a custom type:

- `groovy`: GroovySourceDirectorySet

- `antlr`: AntlrSourceDirectorySet

- `scala`: ScalaSourceDirectorySet

The 'idiomatic' DSL declaration is backward compatible:

    sourceSets {
        main {
            groovy {
                // ...
            }
        }
    }

However, the return type of the groovy block has changed to the extension type. This means that the following snippet no longer works in Gradle 7.1:

     sourceSets {
         main {
             GroovySourceSet sourceSet = groovy {
                 // ...
             }
         }
     }

### Deprecations

#### Using convention mapping with properties with type Provider is deprecated

Convention mapping is an internal feature that is been replaced by the Provider API. When mixing convention mapping with the Provider API, unexpected behavior can occur. Gradle emits a deprecation warning when a property in a task, extension or other domain object uses convention mapping with the Provider API.

To fix this, the plugin that configures the convention mapping for the task, extension or domain object needs to be changed to use the Provider API only.

#### JacocoMerge task type is deprecated

The `JacocoMerge` task was used for merging coverage reports from different subprojects into a single report. The same functionality is also available on the `JacocoReport` task. Because of the duplication, `JacocoMerge` is now deprecated and scheduled for removal in Gradle 8.0.

#### Setting custom build layout

Command line options:

- `-c`, `--settings-file` for specifying a custom settings file location

- `-b`, `--build-file` for specifying a custom build file location

have been deprecated.

Setting custom build file using buildFile property in GradleBuild task has been deprecated.

Please use the dir property instead to specify the root of the nested build. Alternatively, consider using one of the recommended alternatives for GradleBuild task as suggested in Avoid using the GradleBuild task type section.

Setting custom build layout using StartParameter methods setBuildFile(File) and setSettingsFile(File) as well as the counterpart getters getBuildFile() and getSettingsFile() have been deprecated.

Please use standard locations for settings and build files:

- settings file in the root of the build

- build file in the root of each subproject

For the use case where custom settings or build files are used to model different behavior (similar to Maven profiles), consider using system properties with conditional logic. For example, given a piece of code in either settings or build file:

    if (System.getProperty("profile") == "custom") {
        println("custom profile")
    } else {
        println("default profile")
    }

You can pass the `profile` system property to Gradle using `gradle -Dprofile=custom` to execute the code in the `custom` profile branch.

#### Substitution.with replaced with Substitution.using

Dependency substitutions using `with` method have been deprecated and are replaced with `using` method that also allows chaining. For example, a dependency substitution rule `substitute(project(':a')).with(project(':b'))` should be replaced with `substitute(project(':a')).using(project(':b'))`. With chaining you can, for example, add a reason for a substitution like this: `substitute(project(':a')).using(project(':b')).because("a reason")`.

#### Properties deprecated in JavaExec task

- The main getters and setters in JavaExec task have been deprecated. Use the mainClass property instead.

#### Deprecated properties in `compile` task

- The JavaCompile.destinationDir property has been deprecated. Use the JavaCompile.destinationDirectory property instead.

- The GroovyCompile.destinationDir property has been deprecated. Use the GroovyCompile.destinationDirectory property instead.

- The ScalaCompile.destinationDir property has been deprecated. Use the ScalaCompile.destinationDirectory property instead.

#### Deprecated flat project structure

There are several disadvantages of using a flat project structure. One example being that Gradle file-system watching cannot be efficiently used. Because of this, Gradle 7.1 deprecates all layouts that define subprojects outside of a root project directory.

To make this change more visible for plugin author, Gradle 7.1 also deprecates the Settings.includeFlat() method.

#### Deprecated `Upload` task

Gradle used to have two ways of publishing artifacts. Now, the situation has been cleared and all build should use the `maven-publish` plugin. The last remaining artifact of the old way of publishing is the `Upload` task that has been deprecated and scheduled for removal in Gradle 8.0. Existing clients should migrate to the `maven-publish` plugin.

The concept of conventions is outdated and superseded by extensions. To reflect this in the Gradle API, the following elements are now deprecated:

- Project.html#getConvention()

- HasConvention

The internal usages of conventions have been also cleaned up (see the deprecated items below).

Plugin authors migrate to extensions if they replicate the changes we’ve done internally. Here are some examples:

- Migrate plugin configuration: gradle/gradle#16900.

- Migrate custom source sets: gradle/gradle#17149.

#### Deprecated `base` plugin conventions

The convention properties contributed by the `base` plugin have been deprecated and scheduled for removal in Gradle 8.0. The conventions are replaced by the the `base { }` configuration block backed by BasePluginExtension.

The old convention object defines the `distsDirName`, `libsDirName` and `archivesBaseName` properties with simple getter and setter methods. Those methods are available in the extension only to maintain backwards compatibility. Build scripts should solely use the properties of type `Property`:

    base {
        archivesName = 'customBase'
        distsDirectory = layout.buildDirectory.dir('custom-dist')
        libsDirectory = layout.buildDirectory.dir('custom-libs')
    }

#### Deprecated `ApplicationPluginConvention`

ApplicationPluginConvention was already listed as deprecated in the <<application_plugin.adoc#application_convention_properties, documentation>. Now, it is officially annotated as deprecated and scheduled for removal in Gradle 8.0.

#### Deprecated `java` plugin conventions

The convention properties contributed by the `java` plugin have been deprecated and scheduled for removal in Gradle 8.0. They are replaced by the the properties of JavaPluginExtension which can we configured in the `java {}` block.

#### Deprecated consumption of internal plugin configurations

Some of the core Gradle plugins declare configurations that are used by the plugin itself and are not meant to be published or consumed by another subproject directly. Gradle did not explicitly prohobit this. Gradle 7.1 deprecates consumption of those configurations and this will become an error in Gradle 8.0.

The following plugin configurations have been deprecated for consumption:

plugin | configurations deprecated for consumption
--- | ---
`codenarc` | `codenarc`
`pmd` | `pmd`
`checkstyle` | `checkstyle`
`antlr` | `antlr`
`jacoco` | `jacocoAnt`, `jacocoAgent`
`scala` | `zinc`
`war` | `providedCompile`, `providedRuntime`

If your use case needs to consume any of the above mentioned configurations in another project, please create a separate consumable configuration that extends from the internal ones. For example:

    plugins {
        id("codenarc")
    }
    configurations {
        codenarc {
            // because currently this is consumable until Gradle 8.0 and can clash with the configuration below depending on the attributes set
            canBeConsumed = false
        }
        codenarcConsumable {
            extendsFrom(codenarc)
            canBeConsumed = true
            canBeResolved = false
            // the attributes below make this configuration consumable by a `java-library` project using `implementation` configuration
            attributes {
                attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
                attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.LIBRARY))
                attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, LibraryElements.JAR))
                attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling, Bundling.EXTERNAL))
                attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(TargetJvmEnvironment, TargetJvmEnvironment.STANDARD_JVM));
            }
        }
    }

#### Deprecated `project-report` plugin conventions

ProjectReportsPluginConvention is now deprecated and scheduled for removal in Gradle 8.0. Clients should configure the project report tasks directly. Also, tasks.withType(…​).configureEach(…​) can be used to configure each task of the same type (`HtmlDependencyReportTask` for example).

#### Deprecated `war` plugin conventions

WarPluginConvention is now deprecated and scheduled for removal in Gradle 8.0. Clients should configure the `war` task directly. Also, tasks.withType(War.class).configureEach(…​) can be used to configure each task of type `War`.

#### Deprecated `ear` plugin conventions

EarPluginConvention is now deprecated and scheduled for removal in Gradle 8.0. Clients should configure the `ear` task directly. Also, tasks.withType(War.class).configureEach(…​) can be used to configure each task of type `Ear`.

#### Deprecated custom source set interfaces

The following source set interfaces are now deprecated and scheduled for removal in Gradle 8.0:

- GroovySourceSet

- AntlrSourceDirectorySet

- ScalaSourceSet

Clients should configure the sources with their plugin-specific configuration: - `groovy`: GroovySourceDirectorySet - `antlr`: AntlrSourceDirectorySet - `scala`: ScalaSourceDirectorySet

For example, here’s how you configure the groovy sources from a plugin:

    GroovySourceDirectorySet groovySources = sourceSet.getExtensions().getByType(GroovySourceDirectorySet.class);
    groovySources.setSrcDirs(Arrays.asList("sources/groovy"));

#### Registering artifact transforms extending `ArtifactTransform`

When Gradle first introduced artifact transforms, it used the base class `ArtifactTransform` for implementing them. Gradle 5.3 introduced the interface `TransformAction` for implementing artifact transforms, replacing the previous class `ArtifactTransform` and addressing various shortcomings. Using the registration method DependencyHandler.registerTransform(Action) for `ArtifactTransform` has been deprecated. Migrate your artifact transform to use `TransformAction` and use DependencyHandler.registerTransform(Class, Action) instead. See the user manual for more information on implementing `TransformAction`.