Upgrading within Gradle 8.x
在 Gradle 8.x 中升级
- Upgrading from 8.13 and earlier
从8.13及更早版本升级 - Upgrading from 8.12 and earlier
从8.12及更早版本升级 - Upgrading from 8.11 and earlier
从8.11及更早版本升级 - Upgrading from 8.10 and earlier
从8.10及更早版本升级 - Upgrading from 8.9 and earlier
从8.9及更早版本升级 - Upgrading from 8.8 and earlier
从8.8及更早版本升级 - Upgrading from 8.7 and earlier
从8.7及更早版本升级 - Upgrading from 8.6 and earlier
从8.6及更早版本升级 - Upgrading from 8.5 and earlier
从8.5及更早版本升级 - Upgrading from 8.4 and earlier
从8.4及更早版本升级 - Upgrading from 8.3 and earlier
从8.3及更早版本升级 - Upgrading from 8.2 and earlier
从8.2及更早版本升级 - Upgrading from 8.1 and earlier
从8.1及更早版本升级 - Upgrading from 8.0 and earlier
从8.0及更早版本升级
This chapter provides the information you need to migrate your Gradle 8.x builds to Gradle 8.14.3.
For migrating from Gradle 7.x, see the older migration guide first.
本章提供将 Gradle 8.x 版本迁移到 Gradle 8.14.3 所需的信息。要从 Gradle 7.x 迁移,请首先参阅旧版迁移指南 。
We recommend the following steps for all users:
我们向所有用户推荐以下步骤:
-
Try running
gradle help --scanand view the deprecations view of the generated Build Scan.
尝试运行gradle help --scan并查看生成的 Build Scan 的 deprecations 视图 。
This lets you see any deprecation warnings that apply to your build.
这使您可以看到适用于您的构建的任何弃用警告。Alternatively, you can run
gradle help --warning-mode=allto see the deprecations in the console, though it may not report as much detailed information.
或者,您可以运行gradle help --warning-mode=all来查看控制台中的弃用,尽管它可能不会报告那么详细的信息。 -
Update your plugins. 更新您的插件。
Some plugins will break with this new version of Gradle 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 tries to use a deprecated part of the API.
一些插件将与这个新版本的 Gradle 中断,因为它们使用的内部 API 已被删除或更改。上一步将通过在插件尝试使用 API 的弃用部分时发出弃用警告来帮助您识别潜在问题。 -
Run
gradle wrapper --gradle-version 8.14.3to update the project to 8.14.3.
运行gradle wrapper --gradle-version 8.14.3以将项目更新到8.14.3。 -
Try to run the project and debug any errors using the Troubleshooting Guide.
尝试运行项目并使用故障排除指南调试任何错误。
Upgrading from 8.13 and earlier
从8.13及更早版本升级
Potential breaking changes
潜在的突破性变化
The Gradle Wrapper is now an executable JAR
Gradle Wrapper 现在是一个可执行文件
The Gradle Wrapper JAR has been converted into an executable JAR.
This means it now includes a Main-Class attribute, allowing it to be launched using the -jar option instead of specifying a classpath and main class manually.
Gradle Wrapper 插件已转换为可执行插件。这意味着它现在包括一个 Main-Class 属性,允许使用 -jar 选项启动它,而不是手动指定类路径和主类。
When you update the wrapper scripts using the gradle wrapper or ./gradlew wrapper command, the wrapper JAR will be updated automatically to reflect this change.
当您使用 gradle 包装器或更新包装器脚本时 。gradlew wrapper 命令,则包装器将自动更新以反映此更改。
Changes to Settings defaults
更改设置默认值
The incubating Settings.getDefaults() method, introduced in Gradle 8.10, has been removed.
Use the Settings.defaults(Action<SharedModelDefaults>) method instead, which accepts a lambda.
Gradle 8.10 中引入的孵化 Settings. getData() 方法已被删除。改为使用 Settings.defaults(Action<SharedModelDefaults>) 方法,该方法接受 lambda。
This change allows default values to be interpreted in the context of individual projects rather than at the Settings level.
此更改允许在单个项目的上下文中而不是在设置级别解释默认值。
Upgrade to Guava 33.4.6
升级到 Guava 33.4.6
Guava has been updated from version 32.1.2 to 33.4.6.
This release deprecates several core features, including Charsets.
For full details, see the Guava release notes.
Guava 已从版本 32.1.2 更新到 33.4.6。此版本弃用了几个核心功能,包括 Charsets。有关详细信息,请参阅 Guava 发行说明 。
EclipseClasspath.baseSourceOutputDir is now a DirectoryProperty
EclipseClasspath.baseSourceOutputDir 现在是 DirectoryProperty
The incubating EclipseClasspath.baseSourceOutputDir was previously declared as a Property<File>.
It has now been correctly updated to a DirectoryProperty to reflect the intended type.
孵化中的 EclipseClasspath.baseSourceOutputDir 以前被声明为属性<File>。它现在已正确更新为 DirectoryProperty 以反映预期的类型。
Upgrade to Groovy 3.0.24
升级到 Groovy 3.0.24
Groovy has been updated to Groovy 3.0.24.
Groovy 已经更新到 Groovy 3.0.24。
Since the previous version was 3.0.22, this includes changes for Groovy 3.0.23 as well.
由于上一个版本是 3.0.22,因此这也包括 Groovy 3.0.23 的更改。
JavaExec now uses the toolchain from the java extension by default
JavaExec 现在默认使用 java 扩展中的工具链
Previously, the JavaExec task used the same Java version as the Gradle process itself.
Starting in Gradle 9.0, when the java-base plugin is applied, JavaExec will instead default to the Java toolchain configured in the java extension.
You can override the toolchain explicitly in the JavaExec task configuration if needed.
以前,JavaExec 任务使用与 Gradle 进程本身相同的 Java 版本。从 Gradle 9.0 开始,当应用基于 Java 的插件时,JavaExec 将默认使用在 Java 扩展中配置的 Java 工具链。如果需要,您可以在 JavaExec 任务配置中显式地覆盖工具链。
Deprecations 弃用
Looking up attributes using null keys is deprecated
不建议使用空键查找属性
Passing null to getAttribute(Attribute) is now explicitly deprecated.
将 null 传递给 getAttribute(Attribute) 现在已显式弃用。
Previously, this would silently return null.
Now, a deprecation warning is emitted.
There should be no need to perform lookups with null keys in an AttributeContainer.
以前,这会默默地返回 null。现在,发出了一个弃用警告。不需要在 AttributeContainer 中使用空键执行查找。
Groovy string-to-enum coercion for Property types is deprecated
不推荐使用 Groovy 对 Property 类型的字符串到枚举强制转换
Groovy supports string-to-enum coercion.
Assigning a String to a Property<T> where T is an enum is now deprecated.
This will become an error in Gradle 10.
Groovy 支持字符串到枚举强制转换 。将字符串转换为其中 T 是枚举的属性<T> 现在不推荐使用。这将成为 Gradle 10 中的错误。
This deprecation only affects plugins written in Groovy using the Groovy DSL.
这种弃用只影响使用 Groovy DSL 用 Groovy 编写的插件。
Groovydoc.getAntGroovydoc() and org.gradle.api.internal.tasks.AntGroovydoc have been deprecated
Groovydoc.getAntGroovydoc() 和 org.gradle.api.internal.tasks.AntGroovydoc 已弃用
These internal APIs were inadvertently exposed and are now deprecated.
They will be removed in Gradle 9.0.
这些内部 API 无意中暴露,现在已弃用。它们将在 Gradle 9.0 中删除。
Deprecated methods in GradlePluginDevelopmentExtension
GradlePluginDevelopmentExtension 中已弃用的方法
The constructor for GradlePluginDevelopmentExtension and its pluginSourceSet method are now deprecated.
GradlePluginDevelopmentExtension 的构造函数及其 pluginSourceSet 方法现在已弃用。
These methods should not be used directly, they are intended to be configured solely by the Gradle Plugin Development plugin.
Only the main source set is supported for plugin development.
这些方法不应直接使用,它们仅由 Gradle 插件开发插件配置。插件开发只支持主源集。
These methods will be removed in Gradle 9.0.
这些方法将在 Gradle 9.0 中删除。
Deprecated collections in IdeaModule now emit warnings
The testResourcesDirs and testSourcesDirs properties in org.gradle.plugins.ide.idea.model.IdeaModule were marked @Deprecated in Gradle 7.6, but no warnings were emitted until now.
Gradle now emits deprecation warnings when these properties are used.
They will be removed in Gradle 9.0.
Gradle 现在在使用这些属性时会发出弃用警告。它们将在 Gradle 9.0 中删除。
The ForkOptions.getJavaHome() and ForkOptions.setJavaHome() methods are no longer deprecated
These methods were deprecated in Gradle 8.11, but are no longer deprecated, as they do not yet have stable replacements.
Deprecated StartParameter.isConfigurationCacheRequested now emits warnings
The isConfigurationCacheRequested property in StartParameter was marked @Deprecated in Gradle 8.5, but no warnings were emitted until now.
Gradle now emits deprecation warnings when this property is used. It will be removed in Gradle 10.
Since Gradle 8.5, the same information can be obtained via the BuildFeatures service using configurationCache.requested property.
Deprecated configuration usages are no longer deprecated
Starting in 8.0, adding an artifact to a configuration that is neither resolvable nor consumable was deprecated. This deprecation was overly broad and also captured certain valid usages. It has been removed in Gradle 8.14.
Upgrading from 8.12 and earlier
Potential breaking changes
Changes to JvmTestSuite
The testType property was removed from JvmTestSuite and both the TestSuiteTargetName and TestSuiteType attributes have been removed.
Test reports and JaCoCo reports can now be aggregated between projects by specifying the name of the test suite in the target project to aggregate.
See below for additional details.
Changes to Test Report Aggregation and Jacoco Aggregation
Several changes have been made to the incubating Test Report Aggregation and JaCoCo Report Aggregation plugins.
The plugins now create a single test results variant for each test suite, containing all test results for the entire suite, instead of one variant for each test target. This change allows the aggregation plugins to aggregate test suites with multiple targets, where previously this would result in an ambiguous variant selection error.
In the future, as we continue to develop these plugins, we plan to once again create one results variant per test suite target, allowing test results from certain targets to be explicitly aggregated.
The testType property on JacocoCoverageReport and AggregateTestReport has been removed and replaced with a new testSuiteName property:
Previously:
reporting {
reports {
val testCodeCoverageReport by creating(JacocoCoverageReport::class) {
testType = TestSuiteType.UNIT_TEST
}
}
}
Now:
reporting {
reports {
val testCodeCoverageReport by creating(JacocoCoverageReport::class) {
testSuiteName = "test"
}
}
}
Changed behavior when calling BuildLauncher.addJvmArguments
Issue (#31426) was fixed, that caused BuildLauncher.addJvmArguments to override flags coming from the org.gradle.jvmargs system property.
Please ensure that you are not relying on this behavior when upgrading to Gradle 8.13.
If system properties needs to be overridden, BuildLauncher.setJvmArguments should be used instead.
val buildLauncher: BuildLauncher = connector.connect().newBuild()
buildLauncher.setJvmArguments("-Xmx2048m", "-Dmy.custom.property=value")
Upgrade to ASM 9.7.1
ASM was upgraded from 9.6 to 9.7.1 to ensure earlier compatibility for Java 24.
Source level deprecation of Project.task methods
Eager task creation methods on the Project interface have been marked @Deprecated and will generate compiler and IDE warnings when used in build scripts or plugin code.
There is not yet a Gradle deprecation warning emitted for their use.
However, if the build is configured to fail on warnings during Kotlin script or plugin code compilation, this change may cause the build to fail.
A standard Gradle deprecation warning will be printed upon use when these methods are fully deprecated in a future version.
Deprecations
Recursively querying AttributeContainer in lazy provider
In Gradle 9.0, querying the contents of an AttributeContainer from within an attribute value provider of the same container will become an error.
The following example showcases the forbidden behavior:
AttributeContainer container = getAttributeContainer();
Attribute<String> firstAttribute = Attribute.of("first", String.class);
Attribute<String> secondAttribute = Attribute.of("second", String.class);
container.attributeProvider(firstAttribute, project.getProviders().provider(() -> {
// Querying the contents of the container within an attribute value provider
// will become an error.
container.getAttribute(secondAttribute);
return "first";
}));
Deprecated org.gradle.api.artifacts.transform.VariantTransformConfigurationException
There is no good public use case for this exception, and it is not intended to be thrown by users.
It will be replaced by org.gradle.api.internal.artifacts.transform.VariantTransformConfigurationException for internal use only in Gradle 9.0.
Deprecated properties in the incubating UpdateDaemonJvm
The following properties of UpdateDaemonJvm are now deprecated:
-
jvmVersion -
jvmVendor
They are replaced by languageVersion and vendor respectively.
This allows the configuration of a Java toolchain spec and the UpdateDaemonJvm task to be interchangeable.
Note that due to the change of type for the vendor property, executing updateDaemonJvm with the jvmVendor property will result in the task failing.
See the documentation for the new configuration option.
Declaring boolean properties with is-prefix and Boolean types
Gradle property names are derived by following the Java Bean specification with one exception.
Gradle recognizes methods with a Boolean return type and a is-prefix as a boolean property. This is behavior inherited from Groovy originally.
Groovy 4 more closely follows the Java Bean specification and no longer supports this exception.
Gradle will emit a deprecation warning when it detects that a boolean property is derived from a method with a Boolean return type and is-prefix.
In Gradle 9.0, Groovy 4 will no longer recognize this as a property in build scripts and Groovy source files. Gradle’s property-based behavior will not change. Gradle will still consider these properties for up-to-date checks.
In Gradle 10, these methods will no longer be treated as defining a Gradle property. This may cause tasks to behave differently when a Boolean property is used as an input.
There are two options to fix this:
-
Introduce a new method that starts with
getinstead ofiswhich has the same behavior. The old method does not need to be removed (in order to preserve binary compatibility), but may need adjustments as indicated below.-
It is recommended to deprecate the
is-method, and then remove it in a future major version.
-
-
Change the type of the property (both get and set) to
boolean. This is a breaking change.
For task input properties using the first option, you should also annotate the old is- method with @Deprecated and @ReplacedBy to ensure it is not used by Gradle.
For example, this code:
class MyValue {
private final Boolean property = Boolean.TRUE;
@Input
Boolean isProperty() { return property; }
}
Should be replaced with the following:
class MyValue {
private final Boolean property = Boolean.TRUE;
@Deprecated
@ReplacedBy("getProperty")
Boolean isProperty() { return property; }
@Input
Boolean getProperty() { return property; }
}
Upgrading from 8.11 and earlier
Potential breaking changes
Upgrade to Kotlin 2.0.21
The embedded Kotlin has been updated from 2.0.20 to Kotlin 2.0.21.
Upgrade to Ant 1.10.15
Ant has been updated to Ant 1.10.15.
Upgrade to Zinc 1.10.4
Zinc has been updated to 1.10.4.
Swift SDK discovery
To determine the location of the Mac OS X SDK for Swift, Gradle now passes the --sdk macosx arguments to xcrun.
This is necessary because the SDK could be discovered inconsistently without this argument across different environments.
Source level deprecation of TaskContainer.create methods
Eager task creation methods on the TaskContainer interface have been marked @Deprecated and will generate compiler and IDE warnings when used in build scripts or plugin code.
There is not yet a Gradle deprecation warning emitted for their use.
However, if the build is configured to fail on warnings during Kotlin script or plugin code compilation, this behavior may cause the build to fail.
A standard Gradle deprecation warning will be printed upon use when these methods are fully deprecated in a future version.
Deprecations
Deprecated Ambiguous Transformation Chains
Previously, when at least two equal-length chains of artifact transforms were available that would produce compatible variants that would each satisfy a resolution request, Gradle would arbitrarily, and silently, pick one.
Now, Gradle emits a deprecation warning that explains this situation:
There are multiple distinct artifact transformation chains of the same length that would satisfy this request. This behavior has been deprecated. This will fail with an error in Gradle 9.0.
Found multiple transformation chains that produce a variant of 'root project :' with requested attributes:
- color 'red'
- texture 'smooth'
Found the following transformation chains:
- From configuration ':squareBlueSmoothElements':
- With source attributes:
- artifactType 'txt'
- color 'blue'
- shape 'square'
- texture 'smooth'
- Candidate transformation chains:
- Transformation chain: 'ColorTransform':
- 'BrokenColorTransform':
- Converts from attributes:
- color 'blue'
- texture 'smooth'
- To attributes:
- color 'red'
- Transformation chain: 'ColorTransform2':
- 'BrokenColorTransform2':
- Converts from attributes:
- color 'blue'
- texture 'smooth'
- To attributes:
- color 'red'
Remove one or more registered transforms, or add additional attributes to them to ensure only a single valid transformation chain exists.
In such a scenario, Gradle has no way to know which of the two (or more) possible transformation chains should be used. Picking an arbitrary chain can lead to inefficient performance or unexpected behavior changes when seemingly unrelated parts of the build are modified. This is potentially a very complex situation and the message now fully explains the situation by printing all the registered transforms in order, along with their source (input) variants for each candidate chain.
When encountering this type of failure, build authors should either:
-
Add additional, distinguishing attributes when registering transforms present in the chain, to ensure that only a single chain will be selectable to satisfy the request
-
Request additional attributes to disambiguate which chain is selected (if they result in non-identical final attributes)
-
Remove unnecessary registered transforms from the build
This will become an error in Gradle 9.0.
init must run alone
The init task must run by itself.
This task should not be combined with other tasks in a single Gradle invocation.
Running init in the same invocation as other tasks will become an error in Gradle 9.0.
For instance, this wil not be allowed:
> gradlew init tasks
Calling Task.getProject() from a task action
Calling Task.getProject() from a task action at execution time is now deprecated and will be made an error in Gradle 10. This method can still be used during configuration time.
The deprecation is only issued if the configuration cache is not enabled. When the configuration cache is enabled, calls to Task.getProject() are reported as configuration cache problems instead.
This deprecation was originally introduced in Gradle 7.4 but was only issued when the STABLE_CONFIGURATION_CACHE feature flag was enabled. That feature flag no longer controls this deprecation.
This is another step towards moving users away from idioms that are incompatible with the configuration cache, which will become the only mode supported by Gradle in a future release.
Please refer to the configuration cache documentation for alternatives to invoking Task.getProject() at execution time that are compatible with the configuration cache.
Groovy "space assignment" syntax
Currently, there are multiple ways to set a property with Groovy DSL syntax:
propertyName = value
setPropertyName(value)
setPropertyName value
propertyName(value)
propertyName value
The latter one, "space-assignment", is a Gradle-specific feature that is not part of the Groovy language.
In regular Groovy, this is just a method call: propertyName(value), and Gradle generates propertyName method in the runtime if this method hasn’t been present already.
This feature may be a source of confusion (especially for new users) and adds an extra layer of complexity for users and the Gradle codebase without providing any significant value.
Sometimes, classes declare methods with the same name, and these may even have semantics that are different from a plain assignment.
These generated methods are now deprecated and will be removed in Gradle 10, and both propertyName value and propertyName(value) will stop working unless the explicit method propertyName is defined.
Use explicit assignment propertyName = value instead.
For explicit methods, consider using the propertyName(value) syntax instead of propertyName value for clarity.
For example, jvmArgs "some", "arg" can be replaced with jvmArgs("some", "arg") or with jvmArgs = ["some", "arg"] for Test tasks.
If you have a big project, to replace occurrences of space-assignment syntax you can use, for example, the following sed command:
find . -name 'build.gradle' -type f -exec sed -i.bak -E 's/([^A-Za-z]|^)(replaceme)[ \t]*([^= \t{])/\1\2 = \3/g' {} +
You should replace replaceme with one or more property names you want to replace, separated by |, e.g. (url|group).
DependencyInsightReportTask.getDependencySpec
The method was deprecated because it was not intended for public use in build scripts.
ReportingExtension.baseDir
ReportingExtension.getBaseDir(), `ReportingExtension.setBaseDir(File), and ReportingExtension.setBaseDir(Object) were deprecated.
They should be replaced with ReportingExtension.getBaseDirectory() property.
Upgrading from 8.10 and earlier
Potential breaking changes
Upgrade to Kotlin 2.0.20
The embedded Kotlin has been updated from 1.9.24 to Kotlin 2.0.20. Also see the Kotlin 2.0.10 and Kotlin 2.0.0 release notes.
The default kotlin-test version in JVM test suites has been upgraded to 2.0.20 as well.
Kotlin DSL scripts are still compiled with Kotlin language version set to 1.8 for backward compatibility.
Gradle daemon JVM configuration via toolchain
The type of the property UpdateDaemonJvm.jvmVersion is now Property<JavaLanguageVersion>.
If you configured the task in a build script, you will need to replace:
jvmVersion = JavaVersion.VERSION_17
With:
jvmVersion = JavaLanguageVersion.of(17)
Using the CLI options to configure which JVM version to use for the Gradle Daemon has no impact.
使用 CLI 选项配置 Gradle 守护程序使用的 JVM 版本没有影响。
Name matching changes 名称匹配更改
The name-matching logic has been updated to treat numbers as word boundaries for camelCase names.
Previously, a request like unique would match both uniqueA and unique1.
Such a request will now fail due to ambiguity. To avoid issues, use the exact name instead of a shortened version.
名称匹配逻辑已更新,可以将数字视为 camelCase 名称的单词边界。以前,像 unique 这样的请求会同时匹配 uniqueA 和 unique1。这样的请求现在由于不明确而失败。为了避免问题,请使用确切的名称而不是缩短的版本。
This change impacts: 这一变化影响:
-
Task selection 任务选择
-
Project selection 项目选择
-
Configuration selection in dependency report tasks
依赖关系报告任务中的配置选择
Deprecations 弃用
Deprecated JavaHome property of ForkOptions
ForkOptions 的 JavaHome 属性已弃用
The JavaHome property of the ForkOptions type has been deprecated and will be removed in Gradle 9.0.ForkOptions 类型的 JavaHome 属性已被弃用,并将在 Gradle 9.0 中删除。
Use JVM Toolchains, or the executable property instead.
使用 JVM 工具链或可执行属性。
Deprecated mutating buildscript configurations
已弃用的可变构建脚本配置
Starting in Gradle 9.0, mutating configurations in a script’s buildscript block will result in an error.
This applies to project, settings, init, and standalone scripts.
从 Gradle 9.0 开始,更改脚本的 buildscript 块中的配置将导致错误。这适用于项目、设置、初始化和独立脚本。
The buildscript configurations block is only intended to control buildscript classpath resolution.
buildscript 配置块仅用于控制 buildscript 类路径解析。
Consider the following script that creates a new buildscript configuration in a Settings script and resolves it:
考虑以下脚本,它在设置脚本中创建新的 buildscript 配置并解析它:
buildscript {
configurations {
create("myConfig")
}
dependencies {
"myConfig"("org:foo:1.0")
}
}
val files = buildscript.configurations["myConfig"].files
This pattern is sometimes used to resolve dependencies in Settings, where there is no other way to obtain a Configuration. Resolving dependencies in this context is not recommended. Using a detached configuration is a possible but discouraged alternative.
The above example can be modified to use a detached configuration:
val myConfig = buildscript.configurations.detachedConfiguration(
buildscript.dependencies.create("org:foo:1.0")
)
val files = myConfig.files
Selecting Maven variants by configuration name
按配置名称选择 Maven 变体
Starting in Gradle 9.0, selecting variants by name from non-Ivy external components will be forbidden.
从 Gradle 9.0 开始,将禁止从非 Ivy 外部组件中按名称选择变体。
Selecting variants by name from local components will still be permitted; however, this pattern is discouraged.
Variant aware dependency resolution should be preferred over selecting variants by name for local components.
仍然允许从本地组件中按名称选择变体;但是,不鼓励使用此模式。变体感知依赖性解析应该优先于通过本地组件的名称选择变体。
The following dependencies will fail to resolve when targeting a non-Ivy external component:
以下依赖项在针对非 Ivy 外部组件时将无法解析:
dependencies {
implementation(group: "com.example", name: "example", version: "1.0", configuration: "conf")
implementation("com.example:example:1.0") {
targetConfiguration = "conf"
}
}
Deprecated manually adding to configuration container
不推荐手动添加到配置容器
Starting in Gradle 9.0, manually adding configuration instances to a configuration container will result in an error.
Configurations should only be added to the container through the eager or lazy factory methods.
Detached configurations and copied configurations should not be added to the container.
从 Gradle 9.0 开始,手动将配置实例添加到配置容器将导致错误。应该只通过 eager 或 lazy 工厂方法向容器中添加对象。不应将分离的配置和复制的配置添加到容器中。
Calling the following methods on ConfigurationContainer will be forbidden:
- add(Configuration)
- addAll(Collection)
- addLater(Provider)
- addAllLater(Provider)
将禁止在配置容器上调用以下方法:- add(Configuration)- addAll(Collection)- addLater(Provider)- addAllLater(Provider)
Deprecated ProjectDependency#getDependencyProject()
The ProjectDependency#getDependencyProject() method has been deprecated and will be removed in Gradle 9.0.
Accessing the mutable project instance of other projects should be avoided.
To discover details about all projects that were included in a resolution, inspect the full ResolutionResult. Project dependencies are exposed in the DependencyResult. See the user guide section on programmatic dependency resolution for more details on this API. This is the only reliable way to find all projects that are used in a resolution. Inspecting only the declared `ProjectDependency`s may miss transitive or substituted project dependencies.
To get the identity of the target project, use the new Isolated Projects safe project path method: ProjectDependency#getPath().
To access or configure the target project, consider this direct replacement:
val projectDependency: ProjectDependency = getSomeProjectDependency()
// Old way:
val someProject = projectDependency.dependencyProject
// New way:
val someProject = project.project(projectDependency.path)
This approach will not fetch project instances from different builds.
Deprecated ResolvedConfiguration.getFiles() and LenientConfiguration.getFiles()
The ResolvedConfiguration.getFiles() and LenientConfiguration.getFiles() methods have been deprecated and will be removed in Gradle 9.0.
These deprecated methods do not track task dependencies, unlike their replacements.
这些不推荐使用的方法不跟踪任务依赖关系,不像它们的替代品。
val deprecated: Set<File> = conf.resolvedConfiguration.files
val replacement: FileCollection = conf.incoming.files
val lenientDeprecated: Set<File> = conf.resolvedConfiguration.lenientConfiguration.files
val lenientReplacement: FileCollection = conf.incoming.artifactView {
isLenient = true
}.files
Deprecated AbstractOptions
AbstractOptions
The AbstractOptions class has been deprecated and will be removed in Gradle 9.0.
All classes extending AbstractOptions will no longer extend it.AbstractOptions 类已被弃用,并将在 Gradle 9.0 中删除。所有扩展 AbstractOptions 的类将不再扩展它。
As a result, the AbstractOptions#define(Map) method will no longer be present.
This method exposes a non-type-safe API and unnecessarily relies on reflection.
It can be replaced by directly setting the properties specified in the map.
因此,AbstractOptions#define(Map) 方法将不再存在。此方法公开非类型安全的 API,并且不必要地依赖反射。可以通过直接设置映射中指定的属性来替换它。
Additionally, CompileOptions#fork(Map), CompileOptions#debug(Map), and GroovyCompileOptions#fork(Map), which depend on define, are also deprecated for removal in Gradle 9.0.
此外,依赖于 define 的 eOptions #fork(Map)、eOptions #debug(Map) 和 GroovyCompileOptions#fork(Map) 也不推荐在 Gradle 9.0 中删除。
Consider the following example of the deprecated behavior and its replacement:
考虑以下不推荐使用的行为及其替换的示例:
tasks.withType(JavaCompile) {
// Deprecated behavior
options.define(encoding: 'UTF-8')
options.fork(memoryMaximumSize: '1G')
options.debug(debugLevel: 'lines')
// Can be replaced by
options.encoding = 'UTF-8'
options.fork = true
options.forkOptions.memoryMaximumSize = '1G'
options.debug = true
options.debugOptions.debugLevel = 'lines'
}
Deprecated Dependency#contentEquals(Dependency)
The Dependency#contentEquals(Dependency) method has been deprecated and will be removed in Gradle 9.0.
The method was originally intended to compare dependencies based on their actual target component, regardless of whether they were of different dependency type. The existing method does not behave as specified by its Javadoc, and we do not plan to introduce a replacement that does.
Potential migrations include using Object.equals(Object) directly, or comparing the fields of dependencies manually.
Deprecated Project#exec and Project#javaexec
已弃用的项目#exec 和项目#javaexec
The Project#exec(Closure), Project#exec(Action), Project#javaexec(Closure), Project#javaexec(Action) methods have been deprecated and will be removed in Gradle 9.0.Project#exec(Closure)、Project#exec(Action)、Project#javaexec(Closure)、Project#javaexec(Action) 方法已弃用,并将在 Gradle 9.0 中删除。
These methods are scheduled for removal as part of the ongoing effort to make writing configuration-cache-compatible code easier.
There is no way to use these methods without breaking configuration cache requirements so it is recommended to migrate to a compatible alternative.
The appropriate replacement for your use case depends on the context in which the method was previously called.
这些方法计划被删除,作为正在进行的工作的一部分,以使编写配置缓存兼容的代码更容易。如果不破坏配置缓存要求,就无法使用这些方法,因此建议迁移到兼容的替代方法。用例的适当替换取决于方法先前被调用的上下文。
At execution time, for example in @TaskAction or doFirst/doLast callbacks, the use of Project instance is not allowed when the configuration cache is enabled.
To run external processes, tasks should use an injected ExecOperation service, which has the same API and can act as a drop-in replacement.
The standard Java/Groovy/Kotlin process APIs, like java.lang.ProcessBuilder can be used as well.
在执行时,例如在 @TaskAction 或 doFirst/doLast 回调中,启用配置缓存时不允许使用 Project 实例。若要运行外部进程,任务应使用注入的 ExecOperation 服务,该服务具有相同的 API,并可用作直接替代。也可以使用标准的 Java/Groovy/科特林进程 API,如 java.lang.ProcessBuilder。
At configuration time, only special Provider-based APIs must be used to run external processes when the configuration cache is enabled.
You can use ProviderFactory.exec and
ProviderFactory.javaexec to obtain the output of the process.
A custom ValueSource implementation can be used for more sophisticated scenarios.
The configuration cache guide has a more elaborate example of using these APIs.
在配置时,当启用配置缓存时,只能使用特殊的基于提供程序的 API 来运行外部进程。您可以使用 ProviderFactory.exec 和
javaexec 来获取进程的输出。自定义 ValueSource 实现可用于更复杂的场景。 配置缓存指南中有一个更详细的使用这些 API 的示例。
Detached Configurations should not use extendsFrom
分离的扩展不应使用 extendsFrom
Detached configurations should not extend other configurations using extendsFrom.
分离的配置不应使用 extendsFrom 扩展其他配置。
This behavior has been deprecated and will become an error in Gradle 9.0.
此行为已被弃用,并将在 Gradle 9.0 中成为错误。
To create extension relationships between configurations, you should change to using non-detached configurations created via the other factory methods present in the project’s ConfigurationContainer.
要在配置之间创建扩展关系,您应该更改为使用通过项目的 ExtractionContainer 中存在的其他工厂方法创建的非分离配置。
Deprecated customized Gradle logging
已弃用的自定义 Gradle 日志记录
The Gradle#useLogger(Object) method has been deprecated and will be removed in Gradle 9.0.
This method was originally intended to customize logs printed by Gradle. However, it only allows intercepting a subset of the logs and cannot work with the configuration cache. We do not plan to introduce a replacement for this feature.
Unnecessary options on compile options and doc tasks have been deprecated
编译选项和 doc 任务上不必要的选项已被弃用
Gradle’s API allowed some properties that represented nested groups of properties to be replaced wholesale with a setter method.
This was awkward and unusual to do and would sometimes require the use of internal APIs.
The setters for these properties will be removed in Gradle 9.0 to simplify the API and ensure consistent behavior.
Instead of using the setter method, these properties should be configured by calling the getter and configuring the object directly or using the convenient configuration method.
For example, in CompileOptions, instead of calling the setForkOptions setter, you can call getForkOptions() or forkOptions(Action).
Gradle 的 API 允许将一些表示嵌套属性组的属性大规模替换为 setter 方法。这是一件很尴尬的事情,有时需要使用内部 API。这些属性的 setter 将在 Gradle 9.0 中删除,以简化 API 并确保一致的行为。这些属性不应该使用 setter 方法,而应该通过调用 getter 并直接配置对象或使用方便的配置方法来配置。例如,在 SetForkOptions 中,您可以调用 getForkOptions() 或 forkOptions(Action),而不是调用 setForkOptionssetter。
The affected properties are:
受影响的属性为:
Deprecated Javadoc.isVerbose() and Javadoc.setVerbose(boolean)
已弃用的 Javadoc.isVerbose() 和 Javadoc.setVerbose(boolean)
These methods on Javadoc have been deprecated and will be removed in Gradle 9.0.
Javadoc 上的这些方法已被弃用,并将在 Gradle 9.0 中删除。
-
isVerbose() is replaced by getOptions().isVerbose()
isVerbose() 被 getOptions()替换。isVerbose() -
Calling setVerbose(boolean) with
trueis replaced by getOptions().verbose() -
Calling
setVerbose(false)did nothing.
Upgrading from 8.9 and earlier
Potential breaking changes
JavaCompile tasks may fail when using a JRE even if compilation is not necessary
The JavaCompile tasks may sometimes fail when using a JRE instead of a JDK.
This is due to changes in the toolchain resolution code, which enforces the presence of a compiler when one is requested.
The java-base plugin uses the JavaCompile tasks it creates to determine the default source and target compatibility when sourceCompatibility/targetCompatibility or release are not set.
With the new enforcement, the absence of a compiler causes this to fail when only a JRE is provided, even if no compilation is needed (e.g., in projects with no sources).
当使用 JRE 而不是 JDK 时,JavaCompile 任务有时可能会失败。这是由于工具链解析代码的变化,当请求编译器时,它强制编译器的存在。当没有设置 sourceCompatibility/targetCompatibility 或 release 时 ,java-base 插件使用它创建的 JavaCompile 任务来确定默认的源和目标兼容性。在新的实施中,当只提供 JRE 时,即使不需要编译,编译器的缺失也会导致失败(例如,没有来源的项目)。
This can be fixed by setting the sourceCompatibility/targetCompatibility explicitly in the java extension, or by setting sourceCompatibility/targetCompatibility or release in the relevant task(s).
这可以通过在 java 扩展中显式设置 sourceCompatibility/targetCompatibility 来解决,或者通过在相关任务中设置 sourceCompatibility/targetCompatibility 或 release 来解决。
Upgrade to Kotlin 1.9.24
升级到科特林1.9.24
The embedded Kotlin has been updated from 1.9.23 to Kotlin 1.9.24.
嵌入式科特林已从 1.9.23 更新到科特林 1.9.24。
Upgrade to Ant 1.10.14
升级到 Ant 1.10.14
Ant has been updated to Ant 1.10.14.
Ant 已更新到 Ant 1.10.14。
Upgrade to Groovy 3.0.22
升级到 Groovy 3.0.22
Groovy has been updated to Groovy 3.0.22.
Groovy 已经更新到 Groovy 3.0.22。
Deprecations 弃用
Running Gradle on older JVMs
在较旧的 JVM 上运行 Gradle
Starting in Gradle 9.0, Gradle will require JVM 17 or later to run. Most Gradle APIs will be compiled to target JVM 17 bytecode.
从 Gradle 9.0 开始,Gradle 将需要 JVM 17 或更高版本才能运行。大多数 Gradle API 将被编译为针对 JVM 17 字节码。
Gradle will still support compiling Java code to target JVM version 6 or later.
The target JVM version of the compiled code can be configured separately from the JVM version used to run Gradle.
Gradle 仍然支持将 Java 代码编译为目标 JVM 版本 6 或更高版本。编译代码的目标 JVM 版本可以与用于运行 Gradle 的 JVM 版本分开配置。
All Gradle clients (wrapper, launcher, Tooling API and TestKit) will remain compatible with JVM 8 and will be compiled to target JVM 8 bytecode. Only the Gradle daemon will require JVM 17 or later.
These clients can be configured to run Gradle builds with a different JVM version than the one used to run the client:
所有 Gradle 客户端(包装器、启动器、工具 API 和 TestKit)将保持与 JVM 8 兼容,并将编译为目标 JVM 8 字节码。只有 Gradle 守护程序需要 JVM 17 或更高版本。这些客户端可以配置为使用与用于运行客户端的 JVM 版本不同的 JVM 版本来运行 Gradle 构建:
-
Using Daemon JVM criteria (an incubating feature)
使用守护进程 JVM 标准 (孵化特性) -
Setting the
org.gradle.java.homeGradle property
设置org.gradle.java.homeGradle 属性 -
Using the ConfigurableLauncher#setJavaHome method on the Tooling API
在 Tooling API 上使用 SetJavaHome 方法
Alternatively, the JAVA_HOME environment variable can be set to a JVM 17 or newer, which will run both the client and daemon with the same version of the JVM.
或者,可以将 JAVA_HOME 环境变量设置为 JVM 17 或更高版本,这将使用相同版本的 JVM 运行客户端和守护进程。
Running Gradle builds with --no-daemon or using ProjectBuilder in tests will require JVM version 17 or later.
The worker API will remain compatible with JVM 8, and running JVM tests will require JVM 8.
使用 --no-daemon 运行 Gradle 构建或在测试中使用 ProjectBuilder 需要 JVM 版本 17 或更高版本。worker API 将与 JVM 8 保持兼容,运行 JVM 测试将需要 JVM 8。
We decided to upgrade the minimum version of the Java runtime for a number of reasons:
我们决定升级 Java 运行时的最低版本,原因如下:
-
Dependencies are beginning to drop support for older versions and may not release security patches.
安全部门开始放弃对旧版本的支持,可能不会发布安全补丁。 -
Significant language improvements between Java 8 and Java 17 cannot be used without upgrading.
Java 8 和 Java 17 之间的重大语言改进如果不升级就无法使用。 -
Some of the most popular plugins already require JVM 17 or later.
一些最流行的插件已经需要 JVM 17 或更高版本。 -
Download metrics for Gradle distributions show that JVM 17 is widely used.
Gradle 发行版的下载指标显示 JVM 17 被广泛使用。
Deprecated consuming non-consumable configurations from Ivy
来自 Ivy 的不推荐的消耗性非消耗性配置
In prior versions of Gradle, it was possible to consume non-consumable configurations of a project using published Ivy metadata.
An Ivy dependency may sometimes be substituted for a project dependency, either explicitly through the DependencySubstitutions API or through included builds.
When this happens, configurations in the substituted project could be selected that were marked as non-consumable.
在 Gradle 的早期版本中,可以使用已发布的 Ivy 元数据来使用项目的非消耗性配置。Ivy 依赖项有时可能会被项目依赖项替代,无论是通过 DependencySubstitutionAPI 还是通过包含的构建。当这种情况发生时,可以选择被替换项目中被标记为不可消耗的配置。
Consuming non-consumable configurations in this manner is deprecated and will result in an error in Gradle 9.0.
以这种方式使用非耗材配置已被弃用,并将导致 Gradle 9.0 中的错误。
Deprecated extending configurations in the same project
同一项目中不推荐使用的扩展配置
In prior versions of Gradle, it was possible to extend a configuration in a different project.
在以前版本的 Gradle 中,可以在不同的项目中扩展配置。
The hierarchy of a Project’s configurations should not be influenced by configurations in other projects.
Cross-project hierarchies can lead to unexpected behavior when configurations are extended in a way that is not intended by the configuration’s owner.
项目配置的层次结构不应受到其他项目中配置的影响。当配置以配置所有者不希望的方式扩展时,跨项目层次结构可能导致意外行为。
Projects should also never access the mutable state of another project.
Since Configurations are mutable, extending configurations across project boundaries restricts the parallelism that Gradle can apply.
项目也不应该访问另一个项目的可变状态。由于并行性是可变的,因此跨项目边界扩展配置会限制 Gradle 可以应用的并行性。
Extending configurations in different projects is deprecated and will result in an error in Gradle 9.0.
在不同的项目中扩展配置已被弃用,并将导致 Gradle 9.0 中的错误。
Upgrading from 8.8 and earlier
Potential breaking changes
Change to toolchain provisioning
In previous versions of Gradle, toolchain provisioning could leave a partially provisioned toolchain in place with a marker file indicating that the toolchain was fully provisioned.
This could lead to strange behavior with the toolchain.
In Gradle 8.9, the toolchain is fully provisioned before the marker file is written.
However, to not detect potentially broken toolchains, a different marker file (.ready) is used.
This means all your existing toolchains will be re-provisioned the first time you use them with Gradle 8.9.
Gradle 8.9 also writes the old marker file (provisioned.ok) to indicate that the toolchain was fully provisioned.
This means that if you return to an older version of Gradle, an 8.9-provisioned toolchain will not be re-provisioned.
Upgrade to Kotlin 1.9.23
The embedded Kotlin has been updated from 1.9.22 to Kotlin 1.9.23.
Change the encoding of daemon log files
In previous versions of Gradle, the daemon log file, located at $GRADLE_USER_HOME/daemon/9.0.0/, was encoded with the default JVM encoding.
This file is now always encoded with UTF-8 to prevent clients who may use different default encodings from reading data incorrectly.
This change may affect third-party tools trying to read this file.
Compiling against Gradle implementation classpath
In previous versions of Gradle, Java projects that had no declared dependencies could implicitly compile against Gradle’s runtime classes.
This means that some projects were able to compile without any declared dependencies even though they referenced Gradle runtime classes.
This situation is unlikely to arise in projects since IDE integration and test execution would be compromised.
However, if you need to utilize the Gradle API, declare a gradleApi dependency or apply the java-gradle-plugin plugin.
Configuration cache implementation packages now under org.gradle.internal
References to Gradle types not part of the public API should be avoided, as their direct use is unsupported.
Gradle internal implementation classes may suffer breaking changes (or be renamed or removed) from one version to another without warning.
应避免引用不属于公共 API 的 Gradle 类型,因为不支持直接使用这些类型。Gradle 内部实现类可能会在没有警告的情况下从一个版本到另一个版本发生破坏性更改(或被重命名或删除)。
Users need to distinguish between the API and internal parts of the Gradle codebase.
This is typically achieved by including internal in the implementation package names.
However, before this release, the configuration cache subsystem did not follow this pattern.
用户需要区分 Gradle 代码库的 API 和内部部分。这通常通过在实现包名称中包含 internal 来实现。但是,在此版本之前,配置缓存子系统并不遵循此模式。
To address this issue, all code initially under the org.gradle.configurationcache* packages has been moved to new internal packages (org.gradle.internal.*).
为了解决这个问题,最初在 org.gradle.configurationcache* 包下的所有代码都已移动到新的内部包(org.gradle.internal. * ).
File-system watching on macOS 11 (Big Sur) and earlier is disabled
macOS 11(Big Sur)及更早版本上的文件系统监视已禁用
Since Gradle 8.8, file-system watching has only been supported on macOS 12 (Monterey) and later.
We added a check to automatically disable file-system watching on macOS 11 (Big Sur) and earlier versions.
自 Gradle 8.8 以来,仅在 macOS 12(Monterey)及更高版本上支持文件系统监视。我们添加了一项检查,以在 macOS 11(Big Sur)和更早版本上自动禁用文件系统监视。
Possible change to JDK8-based compiler output when annotation processors are used
使用注释处理器时,可能对基于 JDK 8 的编译器输出进行更改
The Java compilation infrastructure has been updated to use the Problems API.
This change will supply the Tooling API clients with structured, rich information about compilation issues.
Java 编译基础结构已更新为使用 Problems API。这一更改将为 Tooling API 客户端提供有关编译问题的结构化的丰富信息。
The feature should not have any visible impact on the usual build output, with JDK8 being an exception.
When annotation processors are used in the compiler, the output message differs slightly from the previous ones.
该特性应该不会对通常的构建输出产生任何可见的影响,JDK 8 是一个例外。当在编译器中使用注释处理器时,输出消息与前面的消息略有不同。
The change mainly manifests itself in typename printed.
For example, Java standard types like java.lang.String will be reported as java.lang.String instead of String.
这种变化主要表现在印刷字体上。例如,Java 标准类型(如 java.lang.String) 将被报告为 java.lang.String 而不是 String。
Upgrading from 8.7 and earlier
从8.7及更早版本升级
Deprecations 弃用
Deprecate mutating configuration after observation
观察后放弃突变配置
To ensure the accuracy of dependency resolution, Gradle checks that Configurations are not mutated after they have been used as part of a dependency graph.
为了确保依赖关系解析的准确性,Gradle 会检查依赖关系在用作依赖关系图的一部分后是否发生了变化。
-
Resolvable configurations should not have their resolution strategy, dependencies, hierarchy, etc., modified after they have been resolved.
可解析配置不应该有其解析策略、依赖关系、层次结构等,在解决后进行修改。 -
Consumable configurations should not have their dependencies, hierarchy, attributes, etc. modified after they have been published or consumed as a variant.
可消费配置在作为变体发布或消费后,不应修改其依赖关系、层次结构、属性等。 -
Dependency scope configurations should not have their dependencies, constraints, etc., modified after a configuration that extends from them is observed.
依赖范围配置不应该有它们的依赖、约束等,在观察到从它们延伸的配置之后修改。
In prior versions of Gradle, many of these circumstances were detected and handled by failing the build.
However, some cases went undetected or did not trigger build failures.
In Gradle 9.0, all changes to a configuration, once observed, will become an error.
After a configuration of any type has been observed, it should be considered immutable.
This validation covers the following properties of a configuration:
在之前版本的 Gradle 中,许多情况都是通过构建失败来检测和处理的。但是,有些情况未被检测到或未触发构建失败。在 Gradle 9.0 中,对配置的所有更改一旦被观察到,将成为错误。在观察到任何类型的配置之后,都应该认为它是不可变的。此验证涵盖配置的以下属性:
-
Resolution Strategy
-
Dependencies
-
Constraints
-
Exclude Rules 排除规则
-
Artifacts 伪影
-
Role (consumable, resolvable, dependency scope)
角色(可消耗、可解析、依赖范围) -
Hierarchy (
extendsFrom)
层次结构(extendsFrom) -
Others (Transitive, Visible)
其他(可传递,可见)
Starting in Gradle 8.8, a deprecation warning will be emitted in cases that were not already an error.
Usually, this deprecation is caused by mutating a configuration in a beforeResolve hook.
This hook is only executed after a configuration is fully resolved but not when it is partially resolved for computing task dependencies.
从 Gradle 8.8 开始,在尚未出现错误的情况下,将发出弃用警告。通常,这种弃用是由 beforeResolve 钩子中的配置变化引起的。此钩子仅在配置完全解析后执行,而不是在部分解析以计算任务依赖关系时执行。
Consider the following code that showcases the deprecated behavior:
考虑以下代码,它展示了不推荐使用的行为:
For the following use cases, consider these alternatives when replacing a beforeResolve hook:
-
Adding dependencies: Use a DependencyFactory and
addLateroraddAllLateron DependencySet. -
Changing dependency versions: Use preferred version constraints.
-
Adding excludes: Use Component Metadata Rules to adjust dependency-level excludes, or withDependencies to add excludes to a configuration.
-
Roles: Configuration roles should be set upon creation and not changed afterward.
-
Hierarchy: Configuration hierarchy (
extendsFrom) should be set upon creation. Mutating the hierarchy prior to resolution is highly discouraged but permitted within a withDependencies hook. -
Resolution Strategy: Mutating a configuration’s ResolutionStrategy is still permitted in a
beforeResolvehook; however, this is not recommended.
Filtered Configuration file and fileCollection methods are deprecated
In an ongoing effort to simplify the Gradle API, the following methods that support filtering based on declared dependencies have been deprecated:
On Configuration:
-
files(Dependency…) -
files(Spec) -
files(Closure) -
fileCollection(Dependency…) -
fileCollection(Spec) -
fileCollection(Closure)
-
getFiles(Spec) -
getFirstLevelModuleDependencies(Spec)
-
getFirstLevelModuleDependencies(Spec) -
getFiles(Spec) -
getArtifacts(Spec)
To mitigate this deprecation, consider the example below that leverages the ArtifactView
API along with the componentFilter method to select a subset of a Configuration’s artifacts:
为了缓解这种不推荐的情况,请考虑下面的示例,该示例利用了 ArtifactView
API 沿着 componentFilter 方法来选择 Configuration 的工件的子集:
KotlinGroovyconfigurations {
conf
}
dependencies {
conf "com.thing:foo:1.0"
conf "org.example:bar:1.0"
}
tasks.register("filterDependencies") {
FileCollection files = configurations.conf.incoming.artifactView {
componentFilter {
it instanceof ModuleComponentIdentifier
&& it.group == "com.thing"
&& it.module == "foo"
}
}.files
doLast {
assert files*.name == ["foo-1.0.jar"]
}
}
Contrary to the deprecated Dependency filtering methods, componentFilter does not consider the transitive dependencies of the component being filtered.
This allows for more granular control over which artifacts are selected.
Deprecated Namer of Task and Configuration
已弃用的任务和配置名称
Task and Configuration have a Namer inner class (also called Namer) that can be used as a common way to retrieve the name of a task or configuration.
Now that these types implement Named, these classes are no longer necessary and have been deprecated.
They will be removed in Gradle 9.0.
Use Named.Namer.INSTANCE instead.Task 和 Configuration 有一个 Namer 内部类(也称为 Namer),可以用作检索任务或配置名称的常用方法。既然这些类型实现了 Named,这些类就不再需要了,并且已经被弃用。它们将在 Gradle 9.0 中删除。请改用 Named.Namer. Brachance。
Unix mode-based file permissions deprecated
不推荐使用基于 Unix 模式的文件权限
A new API for defining file permissions has been added in Gradle 8.3, see:
Gradle 8.3 新增了用于定义文件权限的 API,请参阅:
The new API has now been promoted to stable, and the old methods have been deprecated:
新的 API 现在已经升级为稳定的,旧的方法已经被弃用:
Deprecated setting retention period directly on local build cache
不推荐直接在本地生成缓存上设置保留期
In previous versions, cleanup of the local build cache entries ran every 24 hours, and this interval could not be configured.
The retention period was configured using buildCache.local.removeUnusedEntriesAfterDays.
在以前的版本中,本地生成缓存条目的清理每24小时运行一次,无法配置此间隔。保留期是使用 buildCache.local.removeUnusedEntriesAfterDays 配置的。
In Gradle 8.0, a new mechanism was added to configure the cleanup and retention periods for various resources in Gradle User Home. In Gradle 8.8, this mechanism was extended to permit the retention configuration of local build cache entries, providing improved control and consistency.
-
Specifying
Cleanup.DISABLEDorCleanup.ALWAYSwill now prevent or force the cleanup of the local build cache -
Build cache entry retention is now configured via an
init-script, in the same manner as other caches.
If you want build cache entries to be retained for 30 days, remove any calls to the deprecated method:
buildCache {
local {
// Remove this line
removeUnusedEntriesAfterDays = 30
}
}
Add a file like this in ~/.gradle/init.d:
在 ~/.gradle/init.d 中添加如下文件:
beforeSettings {
caches {
buildCache.setRemoveUnusedEntriesAfterDays(30)
}
}
Calling buildCache.local.removeUnusedEntriesAfterDays is deprecated, and this method will be removed in Gradle 9.0.
If set to a non-default value, this deprecated setting will take precedence over Settings.caches.buildCache.setRemoveUnusedEntriesAfterDays().
Deprecated Kotlin DSL gradle-enterprise plugin block extension
In settings.gradle.kts (Kotlin DSL), you can use gradle-enterprise in the plugins block to apply the Gradle Enterprise plugin with the same version as gradle --scan.
plugins {
`gradle-enterprise`
}
There is no equivalent to this in settings.gradle (Groovy DSL).
Gradle Enterprise has been renamed Develocity, and the com.gradle.enterprise plugin has been renamed com.gradle.develocity.
Therefore, the gradle-enterprise plugin block extension has been deprecated and will be removed in Gradle 9.0.
The Develocity plugin must be applied with an explicit plugin ID and version.
There is no develocity shorthand available in the plugins block:
plugins {
id("com.gradle.develocity") version "3.17.3"
}
If you want to continue using the Gradle Enterprise plugin, you can specify the deprecated plugin ID:
plugins {
id("com.gradle.enterprise") version "3.17.3"
}
We encourage you to use the latest released Develocity plugin version, even when using an older Gradle version.
Potential breaking changes
Changes in the Problems API
We have implemented several refactorings of the Problems API, including a significant change in how problem definitions and contextual information are handled. The complete design specification can be found here.
In implementing this spec, we have introduced the following breaking changes to the ProblemSpec interface:
-
The
label(String)anddescription(String)methods have been replaced with theid(String, String)method and its overloaded variants.
Changes to collection properties
The following incubating API introduced in 8.7 have been removed:
-
MapProperty.insert*(…) -
HasMultipleValues.append*(…)
Replacements that better handle conventions are under consideration for a future 8.x release.
Upgrade to Groovy 3.0.21
升级到 Groovy 3.0.21
Groovy has been updated to Groovy 3.0.21.
Groovy 已经更新到 Groovy 3.0.21。
Since the previous version was 3.0.17, the 3.0.18 and 3.0.19, and 3.0.20 changes are also included.
由于上一版本为 3.0.17,因此还包括 3.0.18 和 3.0.19 以及 3.0.20 的更改。
Some changes in static type checking have resulted in source-code incompatibilities.
Starting with 3.0.18, if you cast a closure to an Action without generics, the closure parameter will be Object instead of any explicit type specified.
This can be fixed by adding the appropriate type to the cast, and the redundant parameter declaration can be removed:
静态类型检查中的一些更改导致了源代码不兼容。从 3.0.18 开始,如果你将一个闭包转换为一个没有泛型的 Action,闭包参数将是 Object 而不是任何指定的显式类型。这可以通过向强制转换添加适当的类型来修复,并且可以删除冗余的参数声明:
// Before
tasks.create("foo", { Task it -> it.description = "Foo task" } as Action)
// Fixed
tasks.create("foo", { it.description = "Foo task" } as Action<Task>)
Upgrade to ASM 9.7
ASM was upgraded from 9.6 to 9.7 to ensure earlier compatibility for Java 23.
Upgrading from 8.6 and earlier
从8.6及更早版本升级
Potential breaking changes
潜在的突破性变化
Upgrade to Kotlin 1.9.22
升级到科特林1.9.22
The embedded Kotlin has been updated from 1.9.10 to Kotlin 1.9.22.
嵌入式科特林已从 1.9.10 更新到科特林 1.9.22。
Replacement and upgrade of JSch
更换和升级 JSch
JSch has been replaced by com.github.mwiede:jsch and updated from 0.1.55 to 0.2.16
JSch 已被 com.github.mwiede:jsch 取代,并从 0.1.55 更新到 0.2.16
Upgrade to Eclipse JGit 5.13.3
升级到 Eclipse JGit 5.13.3
This includes reworking the way that Gradle configures JGit for SSH operations by moving from JSch to Apache SSHD.
这包括通过从 JSch 迁移到 Apache SSHD 来重新调整 Gradle 为 SSH 操作配置 JGit 的方式。
Upgrade to Apache Commons Compress 1.25.0
升级到 Apache Commons Compress 1.25.0
Apache Commons Compress has been updated from 1.21 to 1.25.0.
This change may affect the checksums of the produced jars, zips, and other archive types because the metadata of the produced artifacts may differ.
Apache Commons Compress 已从 1.21 更新到 1.25.0。此更改可能会影响生成的 jar、zip 和其他归档类型的校验和,因为生成的工件的元数据可能会有所不同。
Upgrade to ASM 9.6
ASM was upgraded from 9.5 to 9.6 for better support of multi-release jars.
Upgrade of the version catalog parser
The version catalog parser has been upgraded and is now compliant with version 1.0.0 of the TOML spec.
This should not impact catalogs that use the recommended syntax or were generated by Gradle for publication.
Deprecations
Deprecated registration of plugin conventions
Using plugin conventions has been emitting warnings since Gradle 8.2. Now, registering plugin conventions will also trigger deprecation warnings. For more information, see the section about plugin convention deprecation.
Referencing tasks and domain objects by "name"() in Kotlin DSL
In Kotlin DSL, it is possible to reference a task or other domain object by its name using the "name"() notation.
There are several ways to look up an element in a container by name:
tasks {
"wrapper"() // 1 - returns TaskProvider<Task>
"wrapper"(Wrapper::class) // 2 - returns TaskProvider<Wrapper>
"wrapper"(Wrapper::class) { // 3 - configures a task named wrapper of type Wrapper
}
"wrapper" { // 4 - configures a task named wrapper of type Task
}
}
The first notation is deprecated and will be removed in Gradle 9.0.
Instead of using "name"() to reference a task or domain object, use named("name") or one of the other supported notations.
The above example would be written as:
tasks {
named("wrapper") // returns TaskProvider<Task>
}
The Gradle API and Groovy build scripts are not impacted by this.
Deprecated invalid URL decoding behavior
Before Gradle 8.3, Gradle would decode a CharSequence given to Project.uri(Object) using an algorithm that accepted invalid URLs and improperly decoded others.
Gradle now uses the URI class to parse and decode URLs, but with a fallback to the legacy behavior in the event of an error.
Starting in Gradle 9.0, the fallback will be removed, and an error will be thrown instead.
To fix a deprecation warning, invalid URLs that require the legacy behavior should be re-encoded to be valid URLs, such as in the following examples:
| Original Input | New Input | Reasoning |
|---|---|---|
|
|
The |
|
|
Without a scheme, the path is taken as-is, without decoding. |
|
Spaces are not valid in URLs. |
|
|
||
file::somepath |
somepath |
URIs should be hierarchical. |
Deprecated SelfResolvingDependency
The SelfResolvingDependency interface has been deprecated for removal in Gradle 9.0.
This type dates back to the first versions of Gradle, where some dependencies could be resolved independently.
Now, all dependencies should be resolved as part of a dependency graph using a Configuration.
Currently, ProjectDependency and FileCollectionDependency implement this interface.
In Gradle 9.0, these types will no longer implement SelfResolvingDependency.
Instead, they will both directly implement Dependency.
As such, the following methods of ProjectDependency and FileCollectionDependency will no longer be available:
-
resolve -
resolve(boolean) -
getBuildDependencies
Consider the following scripts that showcase the deprecated interface and its replacement:
考虑以下脚本,它们展示了已弃用的接口及其替代品:
Deprecated members of the org.gradle.util package now report their deprecation
org.gradle.util 包中不推荐使用的成员现在报告它们的不推荐使用
These members will be removed in Gradle 9.0.
这些成员将在 Gradle 9.0 中删除。
-
Collection.stringize(Collection)
Upgrading from 8.5 and earlier
Potential breaking changes
Upgrade to JaCoCo 0.8.11
JaCoCo has been updated to 0.8.11.
DependencyAdder renamed to DependencyCollector
The incubating DependencyAdder interface has been renamed to DependencyCollector.
A getDependencies method has been added to the interface that returns all declared dependencies.
Deprecations
Deprecated calling registerFeature using the main source set
Calling registerFeature on the java extension using the main source set is deprecated and will change behavior in Gradle 10.
Currently, features created while calling usingSourceSet with the main source set are initialized differently than features created while calling usingSourceSet with any other source set.
Previously, when using the main source set, new implementation, compileOnly, runtimeOnly, api, and compileOnlyApi configurations were created, and the compile and runtime classpaths of the main source set were configured to extend these configurations.
Starting in Gradle 10, the main source set will be treated like any other source set.
With the java-library plugin applied (or any other plugin that applies the java plugin), calling usingSourceSet with the main source set will throw an exception.
This is because the java plugin already configures a main feature.
Only if the java plugin is not applied will the main source set be permitted when calling usingSourceSet.
Code that currently registers features with the main source set, such as:
KotlinGroovyplugins {
id("java-library")
}
java {
registerFeature("feature") {
usingSourceSet(sourceSets.main)
}
}
Should instead, create a separate source set for the feature and register the feature with that source set:
相反,应该为该功能创建一个单独的源集,并将该功能注册到该源集:
KotlinGroovy科特林 Groovyplugins {
id("java-library")
}
sourceSets {
feature
}
java {
registerFeature("feature") {
usingSourceSet(sourceSets.feature)
}
}
Deprecated publishing artifact dependencies with explicit name to Maven repositories
Publishing dependencies with an explicit artifact with a name different from the dependency’s artifactId to Maven repositories has been deprecated.
This behavior is still permitted when publishing to Ivy repositories.
It will result in an error in Gradle 9.0.
将带有显式工件的依赖项发布到 Maven 存储库的做法已被弃用,该工件的名称与依赖项的 artifactId 不同。在发布到 Ivy 存储库时仍然允许此行为。这将导致 Gradle 9.0 中出现错误。
When publishing to Maven repositories, Gradle will interpret the dependency below as if it were declared with coordinates org:notfoo:1.0:
当发布到 Maven 仓库时,Gradle 将解释下面的依赖关系,就像它是用坐标 org:notfoo:1.0 声明的一样:
KotlinGroovy科特林 Groovydependencies {
implementation("org:foo:1.0") {
artifact {
name = "notfoo"
}
}
}
Instead, this dependency should be declared as:
相反,此依赖项应声明为:
KotlinGroovy科特林 Groovydependencies {
implementation("org:notfoo:1.0")
}
Deprecated ArtifactIdentifier
弃用的 ArtifactIdentifier
The ArtifactIdentifier class has been deprecated for removal in Gradle 9.0.ArtifactIdentifier 类已弃用,以便在 Gradle 9.0 中删除。
Deprecate mutating DependencyCollector dependencies after observation
观察后弃用变异的 DependencyCollector 依赖项
Starting in Gradle 10, mutating dependencies sourced from a DependencyCollector, after those dependencies have been observed will result in an error.
The DependencyCollector interface is used to declare dependencies within the test suites DSL.
Consider the following example where a test suite’s dependency is mutated after it is observed:
In the above example, the build logic uses iteration and mutation to try to set a default version for a particular dependency if the version is not already set.
Build logic like the above example creates challenges in resolving declared dependencies, as reporting tools will display this dependency as if the user declared the version as "2.0", even though they never did.
Instead, the build logic can avoid iteration and mutation by declaring a preferred version constraint on the dependency’s coordinates.
This allows the dependency management engine to use the version declared on the constraint if no other version is declared.
Consider the following example that replaces the above iteration with an indiscriminate preferred version constraint:
Upgrading from 8.4 and earlier
Potential breaking changes
Upgrade to Kotlin 1.9.20
The embedded Kotlin has been updated to Kotlin 1.9.20.
Changes to Groovy task conventions
The groovy-base plugin is now responsible for configuring source and target compatibility version conventions on all GroovyCompile tasks.
If you are using this task without applying grooy-base, you will have to manually set compatibility versions on these tasks.
In general, the groovy-base plugin should be applied whenever working with Groovy language tasks.
Provider.filter
The type of argument passed to Provider.filter is changed from Predicate to Spec for a more consistent API.
This change should not affect anyone using Provider.filter with a lambda expression.
However, this might affect plugin authors if they don’t use SAM conversions to create a lambda.
Deprecations
Deprecated members of the org.gradle.util package now report their deprecation
These members will be removed in Gradle 9.0:
-
VersionNumber.parse(String) -
VersionNumber.compareTo(VersionNumber)
Deprecated depending on resolved configuration
When resolving a Configuration, selecting that same configuration as a variant is sometimes possible.
Configurations should be used for one purpose (resolution, consumption or dependency declarations), so this can only occur when a configuration is marked as both consumable and resolvable.
This can lead to circular dependency graphs, as the resolved configuration is used for two purposes.
To avoid this problem, plugins should mark all resolvable configurations as canBeConsumed=false or use the resolvable(String) configuration factory method when creating configurations meant for resolution.
In Gradle 9.0, consuming configurations in this manner will no longer be allowed and result in an error.
Including projects without an existing directory
Gradle will warn if a project is added to the build where the associated projectDir does not exist or is not writable.
Starting with version 9.0, Gradle will not run builds if a project directory is missing or read-only.
If you intend to dynamically synthesize projects, make sure to create directories for them as well:
KotlinGroovyinclude 'project-without-directory'
project(":project-without-directory").projectDir.mkdirs()
Upgrading from 8.3 and earlier
Potential breaking changes
Upgrade to Kotlin 1.9.10
The embedded Kotlin has been updated to Kotlin 1.9.10.
XML parsing now requires recent parsers
Gradle 8.4 now configures XML parsers with security features enabled. If your build logic depends on old XML parsers that don’t support secure parsing, your build may fail. If you encounter a failure, check and update or remove any dependency on legacy XML parsers.
If you are an Android user, please upgrade your AGP version to 8.3.0 or higher to fix the issue caused by AGP itself. See the Update XML parser used in AGP for Gradle 8.4 compatibility for more details.
If you are unable to upgrade XML parsers coming from your build logic dependencies, you can force the use of the XML parsers built into the JVM.
In OpenJDK, for example, this can be done by adding the following to gradle.properties:
systemProp.javax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
systemProp.javax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
systemProp.javax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
See the CVE-2023-42445 advisory for more details and ways to enable secure XML processing on previous Gradle versions.
EAR plugin with customized JEE 1.3 descriptor
Gradle 8.4 forbids external XML entities when parsing XML documents.
If you use the EAR plugin and configure the application.xml descriptor via the EAR plugin’s DSL and customize the descriptor using withXml {} and use asElement{} in the customization block, then the build will now fail for security reasons.
KotlinGroovyplugins {
id("ear")
}
ear {
deploymentDescriptor {
version = "1.3"
withXml {
asElement()
}
}
}
If you happen to use asNode() instead of asElement(), then nothing changes, given asNode() simply ignores external DTDs.
You can work around this by running your build with the javax.xml.accessExternalDTD system property set to http.
On the command line, add this to your Gradle invocation:
-Djavax.xml.accessExternalDTD=http
To make this workaround persistent, add the following line to your gradle.properties:
systemProp.javax.xml.accessExternalDTD=http
Note that this will enable HTTP access to external DTDs for the whole build JVM. See the JAXP documentation for more details.
Deprecations
Deprecated GenerateMavenPom methods
The following methods on GenerateMavenPom are deprecated and will be removed in Gradle 9.0.
They were never intended to be public API.
-
getVersionRangeMapper -
withCompileScopeAttributes -
withRuntimeScopeAttributes
Upgrading from 8.2 and earlier
Potential breaking changes
Deprecated Project.buildDir can cause script compilation failure
With the deprecation of Project.buildDir, buildscripts that are compiled with warnings as errors could fail if the deprecated field is used.
See the deprecation entry for details.
TestLauncher API no longer ignores build failures
The TestLauncher interface is part of the Tooling API, specialized for running tests.
It is a logical extension of the BuildLauncher that can only launch tasks.
A discrepancy has been reported in their behavior: if the same failing test is executed, BuildLauncher will report a build failure, but TestLauncher won’t.
Originally, this was a design decision in order to continue the execution and run the tests in all test tasks and not stop at the first failure.
At the same time, this behavior can be confusing for users as they can experience a failing test in a successful build.
To make the two APIs more uniform, we made TestLauncher also fail the build, which is a potential breaking change.
Tooling API clients should explicitly pass --continue to the build to continue the test execution even if a test task fails.
Fixed variant selection behavior with ArtifactView and ArtifactCollection
The dependency resolution APIs for selecting different artifacts or files (Configuration.getIncoming().artifactView { } and Configuration.getIncoming().getArtifacts()) captured immutable copies of the underlying `Configuration’s attributes to use for variant selection.
If the `Configuration’s attributes were changed after these methods were called, the artifacts selected by these methods could be unexpected.
Consider the case where the set of attributes on a Configuration is changed after an ArtifactView is created:
The inputFiles property of myTask uses an artifact view to select a different type of artifact from the configuration classpath.
Since the artifact view was created before the attributes were added to the configuration, Gradle could not select the correct artifact.
Some builds may have worked around this by also putting the additional attributes into the artifact view. This is no longer necessary.
Upgrade to Kotlin 1.9.0
The embedded Kotlin has been updated from 1.8.20 to Kotlin 1.9.0. The Kotlin language and API levels for the Kotlin DSL are still set to 1.8 for backward compatibility. See the release notes for Kotlin 1.8.22 and Kotlin 1.8.21.
Kotlin 1.9 dropped support for Kotlin language and API level 1.3. If you build Gradle plugins written in Kotlin with this version of Gradle and need to support Gradle <7.0 you need to stick to using the Kotlin Gradle Plugin <1.9.0 and configure the Kotlin language and API levels to 1.3. See the Compatibility Matrix for details about other versions.
Eager evaluation of Configuration attributes
Gradle 8.3 updates the org.gradle.libraryelements and org.gradle.jvm.version attributes of JVM Configurations to be present at the time of creation, as opposed to previously, where they were only present after the Configuration had been resolved or consumed.
In particular, the value for org.gradle.jvm.version relies on the project’s configured toolchain, meaning that querying the value for this attribute will finalize the value of the project’s Java toolchain.
Plugins or build logic that eagerly queries the attributes of JVM configurations may now cause the project’s Java toolchain to be finalized earlier than before. Attempting to modify the toolchain after it has been finalized will result in error messages similar to the following:
The value for property 'implementation' is final and cannot be changed any further.
The value for property 'languageVersion' is final and cannot be changed any further.
The value for property 'vendor' is final and cannot be changed any further.
This situation may arise when plugins or build logic eagerly query an existing JVM Configuration’s attributes to create a new Configuration with the same attributes. Previously, this logic would have omitted the two above-noted attributes entirely, while now, the same logic will copy the attributes and finalize the project’s Java toolchain. To avoid early toolchain finalization, attribute-copying logic should be updated to query the source Configuration’s attributes lazily:
KotlinGroovydef source = configurations.runtimeClasspath.attributes
configurations {
customRuntimeClasspath {
source.keySet().each { key ->
attributes.attributeProvider(key, provider { source.getAttribute(key) })
}
}
}
Deprecations
Deprecated Project.buildDir is to be replaced by Project.layout.buildDirectory
The Project.buildDir property is deprecated.
It uses eager APIs and has ordering issues if the value is read in build logic and then later modified.
It could result in outputs ending up in different locations.
It is replaced by a DirectoryProperty found at Project.layout.buildDirectory.
See the ProjectLayout interface for details.
Note that, at this stage, Gradle will not print deprecation warnings if you still use Project.buildDir.
We know this is a big change, and we want to give the authors of major plugins time to stop using it.
Switching from a File to a DirectoryProperty requires adaptations in build logic.
The main impact is that you cannot use the property inside a String to expand it.
Instead, you should leverage the dir and file methods to compute your desired location.
Here is an example of creating a file where the following:
KotlinGroovy// Returns a java.io.File
file("$buildDir/myOutput.txt")
Should be replaced by:
KotlinGroovy// Compatible with a number of Gradle lazy APIs that accept also java.io.File
Provider<RegularFile> output = layout.buildDirectory.file("myOutput.txt")
// If you really need the java.io.File for a non lazy API
output.get().asFile
// Or a path for a lazy String based API
output.map { it.asFile.path }
Here is another example for creating a directory where the following:
KotlinGroovy// Returns a java.io.File
file("$buildDir/outputLocation")
Should be replaced by:
KotlinGroovy// Compatible with a number of Gradle APIs that accept a java.io.File
Provider<Directory> output = layout.buildDirectory.dir("outputLocation")
// If you really need the java.io.File for a non lazy API
output.get().asFile
// Or a path for a lazy String based API
output.map { it.asFile.path }
Deprecated ClientModule dependencies
ClientModule dependencies are deprecated and will be removed in Gradle 9.0.
Client module dependencies were originally intended to allow builds to override incorrect or missing component metadata of external dependencies by defining the metadata locally. This functionality has since been replaced by Component Metadata Rules.
Consider the following client module dependency example:
KotlinGroovydependencies {
implementation module("org:foo:1.0") {
dependency "org:bar:1.0"
module("org:baz:1.0") {
dependency "com:example:1.0"
}
}
}
This can be replaced with the following component metadata rule:
KotlinGroovy@CacheableRule
abstract class AddDependenciesRule implements ComponentMetadataRule {
List<String> dependencies
@Inject
AddDependenciesRule(List<String> dependencies) {
this.dependencies = dependencies
}
@Override
void execute(ComponentMetadataContext context) {
["compile", "runtime"].each { base ->
context.details.withVariant(base) {
withDependencies {
dependencies.each {
add(it)
}
}
}
}
}
}
dependencies {
components {
withModule("org:foo", AddDependenciesRule) {
params([
"org:bar:1.0",
"org:baz:1.0"
])
}
withModule("org:baz", AddDependenciesRule) {
params(["com:example:1.0"])
}
}
implementation "org:foo:1.0"
}
Earliest supported Develocity plugin version is 3.13.1
Starting in Gradle 9.0, the earliest supported Develocity plugin version is 3.13.1. The plugin versions from 3.0 up to 3.13 will be ignored when applied.
Upgrade to version 3.13.1 or later of the Develocity plugin. You can find the latest available version on the Gradle Plugin Portal. More information on the compatibility can be found here.
Upgrading from 8.1 and earlier
Potential breaking changes
Upgrade to Kotlin 1.8.20
The embedded Kotlin has been updated to Kotlin 1.8.20. For more information, see What’s new in Kotlin 1.8.20.
Note that there is a known issue with Kotlin compilation avoidance that can cause OutOfMemory exceptions in compileKotlin tasks if the compilation classpath contains very large JAR files.
This applies to builds applying the Kotlin plugin v1.8.20 or the kotlin-dsl plugin.
You can work around it by disabling Kotlin compilation avoidance in your gradle.properties file:
kotlin.incremental.useClasspathSnapshot=false
See KT-57757 for more information.
Upgrade to Groovy 3.0.17
Groovy has been updated to Groovy 3.0.17.
Since the previous version was 3.0.15, the 3.0.16 changes are also included.
Upgrade to Ant 1.10.13
Ant has been updated to Ant 1.10.13.
Since the previous version was 1.10.11, the 1.10.12 changes are also included.
Upgrade to CodeNarc 3.2.0
The default version of CodeNarc has been updated to CodeNarc 3.2.0.
Upgrade to PMD 6.55.0
PMD has been updated to PMD 6.55.0.
Since the previous version was 6.48.0, all changes since then are included.
Upgrade to JaCoCo 0.8.9
JaCoCo has been updated to 0.8.9.
Plugin compatibility changes
A plugin compiled with Gradle >= 8.2 that makes use of the Kotlin DSL functions Project.the<T>(), Project.the(KClass) or Project.configure<T> {} cannot run on Gradle ⇐ 6.1.
Deferred or avoided configuration of some tasks
When performing dependency resolution, Gradle creates an internal representation of the available Configurations. This requires inspecting all configurations and artifacts. Processing artifacts created by tasks causes those tasks to be realized and configured.
This internal representation is now created more lazily, which can change the order in which tasks are configured. Some tasks may never be configured.
This change may cause code paths that relied on a particular order to no longer function, such as conditionally adding attributes to a configuration based on the presence of certain attributes.
This impacted the bnd plugin and JUnit5 build.
We recommend not modifying domain objects (configurations, source sets, tasks, etc) from configuration blocks for other domain objects that may not be configured.
For example, avoid doing something like this:
例如,避免做这样的事情:
configurations {
val myConfig = create("myConfig")
}
tasks.register("myTask") {
// This is not safe, as the execution of this block may not occur, or may not occur in the order expected
configurations["myConfig"].attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, Usage.JAVA_RUNTIME))
}
}
Deprecations 弃用
CompileOptions method deprecations
不推荐使用的方法
The following methods on CompileOptions are deprecated:
不建议使用以下关于 “选择选项” 的方法:
-
getAnnotationProcessorGeneratedSourcesDirectory() -
setAnnotationProcessorGeneratedSourcesDirectory(File) -
setAnnotationProcessorGeneratedSourcesDirectory(Provider<File>)
Current usages of these methods should migrate to DirectoryProperty getGeneratedSourceOutputDirectory()
这些方法的当前用法应迁移到 DirectoryProperty getGeneratedSourceOutputDirectory()
Using configurations incorrectly
不正确地使用配置
Gradle will now warn at runtime when methods of Configuration are called inconsistently with the configuration’s intended usage.
Gradle 现在将在运行时警告配置方法的调用与配置的预期用途不一致。
This change is part of a larger ongoing effort to make the intended behavior of configurations more consistent and predictable and to unlock further speed and memory improvements.
这一变化是一个更大的持续努力的一部分,使配置的预期行为更加一致和可预测,并解锁进一步的速度和内存改进。
Currently, the following methods should only be called with these listed allowed usages:
目前,以下方法只能在列出的允许用法下调用:
-
resolve()- RESOLVABLE configurations onlyresolve()-仅可解决的配置 -
files(Closure),files(Spec),files(Dependency…),fileCollection(Spec),fileCollection(Closure),fileCollection(Dependency…)- RESOLVABLE configurations onlyfiles(Closure)、files(Spec)、files(Dependency...)、fileCollection(Spec)、fileCollection(Closure)、fileCollection(Dependency...)-仅限 RESOLVABLE 配置 -
getResolvedConfigurations()- RESOLVABLE configurations onlygetResolvedObject()-仅可解决的配置 -
defaultDependencies(Action)- DECLARABLE configurations onlydefaultDuration(操作)-仅限可延迟配置 -
shouldResolveConsistentlyWith(Configuration)- RESOLVABLE configurations only
shouldResolveConsistentlyWith(Configuration)-仅可解决的配置 -
disableConsistentResolution()- RESOLVABLE configurations onlydisableConsistentResolution()-仅适用于可解决的配置 -
getDependencyConstraints()- DECLARABLE configurations onlygetDependencyConstraints()-仅限可延迟配置 -
copy(),copy(Spec),copy(Closure),copyRecursive(),copyRecursive(Spec),copyRecursive(Closure)- RESOLVABLE configurations onlycopy(),copy(Spec),copy(Closure),copyRecursive(),copyRecursive(Spec),copyRecursive(Closure)-仅限 RESOLVABLE 配置
Intended usage is noted in the Configuration interface’s Javadoc.
This list is likely to grow in future releases.
在配置界面的 Javadoc 中注明了预期用途。这个列表在未来的版本中可能会增加。
Starting in Gradle 9.0, using a configuration inconsistently with its intended usage will be prohibited.
从 Gradle 9.0 开始,将禁止使用与其预期用途不一致的配置。
Also note that although it is not currently restricted, the getDependencies() method is only intended for use with DECLARABLE configurations.
The getAllDependencies() method, which retrieves all declared dependencies on a configuration and any superconfigurations, will not be restricted to any particular usage.
还要注意的是,尽管 getExcellencies() 方法目前没有限制,但它只适用于 DEPENABLE 配置。getAllconfigurations() 方法检索所有声明的对配置和任何超级配置的依赖关系,将不限于任何特定的用法。
Deprecated access to plugin conventions
The concept of conventions is outdated and superseded by extensions to provide custom DSLs.
To reflect this in the Gradle API, the following elements are deprecated:
-
org.gradle.api.Project.getConvention() -
org.gradle.api.plugins.Convention -
org.gradle.api.internal.HasConvention
Gradle Core plugins still register their conventions in addition to their extensions for backwards compatibility.
It is deprecated to access any of these conventions and their properties. Doing so will now emit a deprecation warning. This will become an error in Gradle 9.0. You should prefer accessing the extensions and their properties instead.
For specific examples, see the next sections.
Prominent community plugins already migrated to using extensions to provide custom DSLs. Some of them still register conventions for backward compatibility. Registering conventions does not emit a deprecation warning yet to provide a migration window. Future Gradle versions will do.
Also note that Plugins compiled with Gradle ⇐ 8.1 that make use of the Kotlin DSL functions Project.the<T>(), Project.the(KClass) or Project.configure<T> {} will emit a deprecation warning when run on Gradle >= 8.2.
To fix this these plugins should be recompiled with Gradle >= 8.2 or changed to access extensions directly using extensions.getByType<T>() instead.
Deprecated base plugin conventions
The convention properties contributed by the base plugin have been deprecated and scheduled for removal in Gradle 9.0.
For more context, see the section about plugin convention deprecation.
The conventions are replaced by 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 backward compatibility.
Build scripts should solely use the properties of type Property:
KotlinGroovyplugins {
id 'base'
}
base {
archivesName = "gradle"
distsDirectory = layout.buildDirectory.dir('custom-dist')
libsDirectory = layout.buildDirectory.dir('custom-libs')
}
Deprecated application plugin conventions
The convention properties the application plugin contributed have been deprecated and scheduled for removal in Gradle 9.0.
For more context, see the section about plugin convention deprecation.
The following code will now emit deprecation warnings:
KotlinGroovyplugins {
id 'application'
}
applicationDefaultJvmArgs = ['-Dgreeting.language=en'] // Accessing a convention
This should be changed to use the application { } configuration block, backed by JavaApplication, instead:
KotlinGroovyplugins {
id 'application'
}
application {
applicationDefaultJvmArgs = ['-Dgreeting.language=en']
}
Deprecated java plugin conventions
The convention properties the java plugin contributed have been deprecated and scheduled for removal in Gradle 9.0.
For more context, see the section about plugin convention deprecation.
The following code will now emit deprecation warnings:
KotlinGroovyplugins {
id 'java'
}
sourceCompatibility = 18 // Accessing a convention
This should be changed to use the java { } configuration block, backed by JavaPluginExtension, instead:
KotlinGroovyplugins {
id 'java'
}
java {
sourceCompatibility = JavaVersion.VERSION_18
}
Deprecated war plugin conventions
The convention properties contributed by the war plugin have been deprecated and scheduled for removal in Gradle 9.0.
For more context, see the section about plugin convention deprecation.
The following code will now emit deprecation warnings:
KotlinGroovyplugins {
id 'war'
}
webAppDirName = 'src/main/webapp' // Accessing a convention
Clients should configure the war task directly.
Also, tasks.withType(War.class).configureEach(…) can be used to configure each task of type War.
KotlinGroovyplugins {
id 'war'
}
war {
webAppDirectory = file('src/main/webapp')
}
Deprecated ear plugin conventions
The convention properties contributed by the ear plugin have been deprecated and scheduled for removal in Gradle 9.0.
For more context, see the section about plugin convention deprecation.
The following code will now emit deprecation warnings:
KotlinGroovyplugins {
id 'ear'
}
appDirName = 'src/main/app' // Accessing a convention
Clients should configure the ear task directly.
Also, tasks.withType(Ear.class).configureEach(…) can be used to configure each task of type Ear.
KotlinGroovyplugins {
id 'ear'
}
ear {
appDirectory = file('src/main/app') // use application metadata found in this folder
}
Deprecated project-report plugin conventions
The convention properties contributed by the project-reports plugin have been deprecated and scheduled for removal in Gradle 9.0.
For more context, see the section about plugin convention deprecation.
The following code will now emit deprecation warnings:
KotlinGroovyplugins {
id 'project-report'
}
projectReportDirName = "custom" // Accessing a convention
Configure your report task instead:
KotlinGroovyplugins {
id 'project-report'
}
tasks.withType(HtmlDependencyReportTask) {
projectReportDirectory = project.layout.buildDirectory.dir("reports/custom")
}
Configuration method deprecations
The following method on Configuration is deprecated for removal:
-
getAll()
Obtain the set of all configurations from the project’s configurations container instead.
Relying on automatic test framework implementation dependencies
In some cases, Gradle will load JVM test framework dependencies from the Gradle distribution to execute tests. This existing behavior can lead to test framework dependency version conflicts on the test classpath. To avoid these conflicts, this behavior is deprecated and will be removed in Gradle 9.0. Tests using TestNG are unaffected.
To prepare for this change in behavior, either declare the required dependencies explicitly or migrate to Test Suites, where these dependencies are managed automatically.
Test Suites
Builds that use test suites will not be affected by this change. Test suites manage the test framework dependencies automatically and do not require dependencies to be explicitly declared. See the user manual for further information on migrating to test suites.
Manually declaring dependencies
In the absence of test suites, dependencies must be manually declared on the test runtime classpath:
-
If using JUnit 5, an explicit
runtimeOnlydependency onjunit-platform-launcheris required in addition to the existingimplementationdependency on the test engine. -
If using JUnit 4, only the existing
implementationdependency onjunit4 is required. -
If using JUnit 3, a test
runtimeOnlydependency onjunit4 is required in addition to acompileOnlydependency onjunit3.
KotlinGroovydependencies {
// If using JUnit Jupiter
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// If using JUnit Vintage
testCompileOnly 'junit:junit:4.13.2'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.9.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// If using JUnit 4
testImplementation 'junit:junit:4.13.2'
// If using JUnit 3
testCompileOnly 'junit:junit:3.8.2'
testRuntimeOnly 'junit:junit:4.13.2'
}
BuildIdentifier and ProjectComponentSelector method deprecations
The following methods on BuildIdentifier are deprecated:
-
getName() -
isCurrentBuild()
You could use these methods to distinguish between different project components with the same name but from different builds. However, for certain composite build setups, these methods do not provide enough information to guarantee uniqueness.
Current usages of these methods should migrate to BuildIdentifier.getBuildPath().
Similarly, the method ProjectComponentSelector.getBuildName() is deprecated.
Use ProjectComponentSelector.getBuildPath() instead.
Upgrading from 8.0 and earlier
CACHEDIR.TAG files are created in global cache directories
Gradle now emits a CACHEDIR.TAG file in some global cache directories, as specified in directory_layout.html.
This may cause these directories to no longer be searched or backed up by some tools. To disable it, use the following code in an init script in the Gradle User Home:
KotlinGroovybeforeSettings { settings ->
settings.caches {
// Disable cache marking for all caches
markingStrategy = MarkingStrategy.NONE
}
}
Configuration cache options renamed
In this release, the configuration cache feature was promoted from incubating to stable.
As such, all properties originally mentioned in the feature documentation (which had an unsafe part in their names, e.g., org.gradle.unsafe.configuration-cache) were renamed, in some cases, by removing the unsafe part of the name.
| Incubating property | Finalized property |
|---|---|
|
|
|
|
|
|
Note that the original org.gradle.unsafe.configuration-cache… properties continue to be honored in this release,
and no warnings will be produced if they are used, but they will be deprecated and removed in a future release.
Potential breaking changes
Kotlin DSL scripts emit compilation warnings
Compilation warnings from Kotlin DSL scripts are printed to the console output. For example, the use of deprecated APIs in Kotlin DSL will emit warnings each time the script is compiled.
This is a potentially breaking change if you are consuming the console output of Gradle builds.
Configuring Kotlin compiler options with the kotlin-dsl plugin applied
If you are configuring custom Kotlin compiler options on a project with the kotlin-dsl plugin applied you might encounter a breaking change.
In previous Gradle versions, the kotlin-dsl plugin was adding required compiler arguments on afterEvaluate {}.
Now that the Kotlin Gradle Plugin provides lazy configuration properties, our kotlin-dsl plugin switched to adding required compiler arguments to the lazy properties directly.
As a consequence, if you were setting freeCompilerArgs the kotlin-dsl plugin is now failing the build because its required compiler arguments are overridden by your configuration.
With the configuration above you would get the following build failure:
* What went wrong
Execution failed for task ':compileKotlin'.
> Kotlin compiler arguments of task ':compileKotlin' do not work for the `kotlin-dsl` plugin. The 'freeCompilerArgs' property has been reassigned. It must instead be appended to. Please use 'freeCompilerArgs.addAll(\"your\", \"args\")' to fix this.
You must change this to adding your custom compiler arguments to the lazy configuration properties of the Kotlin Gradle Plugin for them to be appended to the ones required by the kotlin-dsl plugin:
If you were already adding to freeCompilerArgs instead of setting its value, you should not experience a build failure.
New API introduced may clash with existing Gradle DSL code
When a new property or method is added to an existing type in the Gradle DSL, it may clash with names already used in user code.
When a name clash occurs, one solution is to rename the element in user code.
This is a non-exhaustive list of API additions in 8.1 that may cause name collisions with existing user code.
Using unsupported API to start external processes at configuration time is no longer allowed with the configuration cache enabled
Since Gradle 7.5, using Project.exec, Project.javaexec, and standard Java and Groovy APIs to run external processes at configuration time has been considered an error only if the feature preview STABLE_CONFIGURATION_CACHE was enabled.
With the configuration cache promotion to a stable feature in Gradle 8.1, this error is detected regardless of the feature preview status.
The configuration cache chapter has more details to help with the migration to the new provider-based APIs to execute external processes at configuration time.
Builds that do not use the configuration cache, or only start external processes at execution time are not affected by this change.
Deprecations
Mutating core plugin configuration usage
The allowed usage of a configuration should be immutable after creation.
Mutating the allowed usage on a configuration created by a Gradle core plugin is deprecated.
This includes calling any of the following Configuration methods:
-
setCanBeConsumed(boolean) -
setCanBeResolved(boolean)
These methods now emit deprecation warnings on these configurations, except for certain special cases which make allowances for the existing behavior of popular plugins.
This rule does not yet apply to detached configurations or configurations created in buildscripts and third-party plugins.
Calling setCanBeConsumed(false) on apiElements or runtimeElements is not yet deprecated in order to avoid warnings that would be otherwise emitted when using select popular third-party plugins.
This change is part of a larger ongoing effort to make the intended behavior of configurations more consistent and predictable, and to unlock further speed and memory improvements in this area of Gradle.
The ability to change the allowed usage of a configuration after creation will be removed in Gradle 9.0.
Reserved configuration names
Configuration names "detachedConfiguration" and "detachedConfigurationX" (where X is any integer) are reserved for internal use when creating detached configurations.
The ability to create non-detached configurations with these names will be removed in Gradle 9.0.
Calling select methods on the JavaPluginExtension without the java component present
Starting in Gradle 8.1, calling any of the following methods on JavaPluginExtension without
the presence of the default java component is deprecated:
-
withJavadocJar() -
withSourcesJar() -
consistentResolution(Action)
This java component is added by the JavaPlugin, which is applied by any of the Gradle JVM plugins including:
-
java-library -
application -
groovy -
scala
Starting in Gradle 9.0, calling any of the above listed methods without the presence of the default java component will become an error.
WarPlugin#configureConfiguration(ConfigurationContainer)
Starting in Gradle 8.1, calling WarPlugin#configureConfiguration(ConfigurationContainer) is deprecated.
This method was intended for internal use and was never intended to be used as part of the public interface.
Starting in Gradle 9.0, this method will be removed without replacement.
Relying on conventions for custom Test tasks
By default, when applying the java plugin, the testClassesDirs`and `classpath of all Test tasks have the same convention.
Unless otherwise changed, the default behavior is to execute the tests from the default test TestSuite by configuring the task with the classpath and testClassesDirs from the test suite.
This behavior will be removed in Gradle 9.0.
While this existing default behavior is correct for the use case of executing the default unit test suite under a different environment, it does not support the use case of executing an entirely separate set of tests.
If you wish to continue including these tests, use the following code to avoid the deprecation warning in 8.1 and prepare for the behavior change in 9.0. Alternatively, consider migrating to test suites.
KotlinGroovytasks.myTestTask {
testClassesDirs = testing.suites.test.sources.output.classesDirs
classpath = testing.suites.test.sources.runtimeClasspath
}
Modifying Gradle Module Metadata after a publication has been populated
Altering the GMM (e.g., changing a component configuration variants) after a Maven or Ivy publication has been populated from their components is now deprecated. This feature will be removed in Gradle 9.0.
Eager population of the publication can happen if the following methods are called:
-
Maven
-
Ivy
Previously, the following code did not generate warnings, but it created inconsistencies between published artifacts:
KotlinGroovypublishing {
publications {
maven(MavenPublication) {
from components.java
}
ivy(IvyPublication) {
from components.java
}
}
}
// These calls eagerly populate the Maven and Ivy publications
publishing.publications.maven.artifacts
publishing.publications.ivy.artifacts
components.java.withVariantsFromConfiguration(configurations.apiElements) { skip() }
components.java.withVariantsFromConfiguration(configurations.runtimeElements) { skip() }
In this example, the Maven and Ivy publications will contain the main JAR artifacts for the project, whereas the GMM module file will omit them.
Running tests on JVM versions 6 and 7
Running JVM tests on JVM versions older than 8 is deprecated. Testing on these versions will become an error in Gradle 9.0
Applying Kotlin DSL precompiled scripts published with Gradle < 6.0
Applying Kotlin DSL precompiled scripts published with Gradle < 6.0 is deprecated. Please use a version of the plugin published with Gradle >= 6.0.
Applying the kotlin-dsl together with Kotlin Gradle Plugin < 1.8.0
Applying the kotlin-dsl together with Kotlin Gradle Plugin < 1.8.0 is deprecated.
Please let Gradle control the version of kotlin-dsl by removing any explicit kotlin-dsl version constraints from your build logic.
This will let the kotlin-dsl plugin decide which version of the Kotlin Gradle Plugin to use.
If you explicitly declare which version of the Kotlin Gradle Plugin to use for your build logic, update it to >= 1.8.0.
Accessing libraries or bundles from dependency version catalogs in the plugins {} block of a Kotlin script
Accessing libraries or bundles from dependency version catalogs in the plugins {} block of a Kotlin script is deprecated.
Please only use versions or plugins from dependency version catalogs in the plugins {} block.
Using ValidatePlugins task without a Java Toolchain
Using a task of type ValidatePlugins without applying the Java Toolchains plugin
—or any other Java plugin that applies the Java Toolchains plugin—was deprecated in Gradle 8.1 and is now an error in Gradle 9.0.
Deprecated members of the org.gradle.util package now report their deprecation
These members will be removed in Gradle 9.0.
-
WrapUtil.toDomainObjectSet(…) -
GUtil.toCamelCase(…) -
GUtil.toLowerCase(…) -
ConfigureUtil
Deprecated JVM vendor IBM Semeru
The enum constant JvmVendorSpec.IBM_SEMERU is now deprecated and will be removed in Gradle 9.0.
Please replace it by its equivalent JvmVendorSpec.IBM to avoid warnings and potential errors in the next major version release.
Setting custom build layout on StartParameter and GradleBuild
Following the related previous deprecation of the behaviour in Gradle 7.1, it is now also deprecated to use related StartParameter and GradleBuild properties. These properties will be removed in Gradle 9.0.
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.
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
Deprecated org.gradle.cache.cleanup property
The org.gradle.cache.cleanup property in gradle.properties under Gradle User Home has been deprecated.
Please use the cache cleanup DSL instead to disable or modify the cleanup configuration.
Since the org.gradle.cache.cleanup property may still be needed for older versions of Gradle, this property may still be present and no deprecation warnings will be printed as long as it is also configured via the DSL.
The DSL value will always take preference over the org.gradle.cache.cleanup property.
If the desired configuration is to disable cleanup for older versions of Gradle (using org.gradle.cache.cleanup), but to enable cleanup with the default values for Gradle versions at or above Gradle 8, then cleanup should be configured to use Cleanup.DEFAULT:
GroovyKotlinif (GradleVersion.current() >= GradleVersion.version('8.0')) {
apply from: "gradle8/cache-settings.gradle"
}
beforeSettings { settings ->
settings.caches {
cleanup = Cleanup.DEFAULT
}
}
beforeSettings {
caches {
cleanup.set(Cleanup.DEFAULT)
}
}
Deprecated using relative paths to specify Java executables
Using relative file paths to point to Java executables is now deprecated and will become an error in Gradle 10. This is done to reduce confusion about what such relative paths should resolve against.
Calling Task.getConvention(), Task.getExtensions() from a task action
Calling Task.getConvention(), Task.getExtensions() from a task action at execution time is now deprecated and will be made an error in Gradle 9.0.
See the configuration cache chapter for details on how to migrate these usages to APIs that are supported by the configuration cache.
Deprecated running test task successfully when no test executed
Running the Test task successfully when no test was executed is now deprecated and will become an error in Gradle 9.
Note that it is not an error when no test sources are present, in this case the test task is simply skipped.
It is only an error when test sources are present, but no test was selected for execution.
This is changed to avoid accidental successful test runs due to erroneous configuration.
Changes in the IDE integration
Workaround for false positive errors shown in Kotlin DSL plugins {} block using version catalog is not needed anymore
Version catalog accessors for plugin aliases in the plugins {} block aren’t shown as errors in IntelliJ IDEA and Android Studio Kotlin script editor anymore.
If you were using the @Suppress("DSL_SCOPE_VIOLATION") annotation as a workaround, you can now remove it.
If you were using the Gradle Libs Error Suppressor IntelliJ IDEA plugin, you can now uninstall it.
After upgrading Gradle to 8.1 you will need to clear the IDE caches and restart.