Gradle 模块元数据是一种用于序列化 Gradle 组件模型的格式。它类似于 Apache Maven™ 的 POM 文件Apache Ivy™ 的 ivy.xml 文件。元数据文件的目标是为消费者提供关于仓库中已发布内容的一个合理模型。

Gradle 模块元数据是一种独特的格式,旨在通过实现跨平台和变体感知来改进依赖解析。

特别是,Gradle 模块元数据支持

发布 Gradle 模块元数据将为您的消费者提供更好的依赖管理

使用Maven Publish 插件Ivy Publish 插件时,Gradle 模块元数据会自动发布。

Gradle 模块元数据的规范可以在此处找到。

与其他格式的映射

Gradle 模块元数据会自动发布到 Maven 或 Ivy 仓库。但是,它不会取代 pom.xmlivy.xml 文件:它会与这些文件一起发布。这样做是为了最大限度地提高与第三方构建工具的兼容性。

Gradle 会尽力将 Gradle 特有的概念映射到 Maven 或 Ivy。当构建文件使用了只能在 Gradle 模块元数据中表示的特性时,Gradle 会在发布时发出警告。下表总结了一些 Gradle 特有特性如何映射到 Maven 和 Ivy

表 1. Gradle 特有概念到 Maven 和 Ivy 的映射
Gradle Maven Ivy 描述

依赖约束

<dependencyManagement> 依赖项

未发布

Gradle 依赖约束是传递性的,而 Maven 的依赖管理块则不是

丰富的版本约束

发布要求的版本

已发布要求的版本

组件能力

未发布

未发布

组件能力是 Gradle 所特有的

特性变体

变体制品会被上传,依赖项会作为可选依赖项发布

变体制品会被上传,依赖项不会发布

特性变体是可选依赖项的良好替代

自定义组件类型

制品会被上传,依赖项是映射所描述的那些

制品会被上传,依赖项会被忽略

自定义组件类型在任何情况下可能都无法从 Maven 或 Ivy 中消费。它们通常存在于自定义生态系统的上下文中。

禁用元数据兼容性发布警告

如果您想抑制警告,可以使用以下 API 来实现

build.gradle.kts
publications {
    register<MavenPublication>("maven") {
        from(components["java"])
        suppressPomMetadataWarningsFor("runtimeElements")
    }
}
build.gradle
publications {
    maven(MavenPublication) {
        from components.java
        suppressPomMetadataWarningsFor('runtimeElements')
    }
}

与其他构建工具的交互

由于 Gradle 模块元数据并未广泛传播,并且其目标是最大化与其他工具的兼容性,因此 Gradle 做了几件事:

  • Gradle 模块元数据会系统地与给定仓库(Maven 或 Ivy)的常规描述符一起发布

  • pom.xmlivy.xml 文件会包含一个标记注释,它告诉 Gradle 此模块存在 Gradle 模块元数据

标记的目的不是让其他工具解析模块元数据:它只供 Gradle 用户使用。它向 Gradle 解释存在一个更好的模块元数据文件,并且它应该使用该文件。这并不意味着从 Maven 或 Ivy 消费时会出错,只是它会以降级模式工作。

这必须视为一种性能优化:Gradle 不必执行两次网络请求(一次获取 Gradle 模块元数据,如果失败再获取 POM/Ivy 文件),而是首先查找最有可能存在的文件,然后只有在模块实际以 Gradle 模块元数据发布时,才会执行第二次请求。

如果您知道您依赖的模块总是与 Gradle 模块元数据一起发布,您可以通过为仓库配置元数据源来优化网络调用

build.gradle.kts
repositories {
    maven {
        url = uri("http://repo.mycompany.com/repo")
        metadataSources {
            gradleMetadata()
        }
    }
}
build.gradle
repositories {
    maven {
        url = "http://repo.mycompany.com/repo"
        metadataSources {
            gradleMetadata()
        }
    }
}

Gradle 模块元数据验证

Gradle 模块元数据在发布前会进行验证。

以下规则会被强制执行:

这些规则确保了所生成元数据的质量,并有助于确认消费过程不会出现问题。

Gradle 模块元数据可重现性

生成模块元数据文件的任务由于其实现方式,目前 Gradle 从未将其标记为 UP-TO-DATE。但是,如果构建输入和构建脚本都没有改变,则该任务结果实际上是最新状态的:它总是产生相同的输出。

如果用户希望每次构建调用都生成唯一的 module 文件,可以在生成的元数据中链接一个标识符到创建它的构建。用户可以在其 publication 中选择启用此唯一标识符

build.gradle.kts
publishing {
    publications {
        create<MavenPublication>("myLibrary") {
            from(components["java"])
            withBuildIdentifier()
        }
    }
}
build.gradle
publishing {
    publications {
        myLibrary(MavenPublication) {
            from components.java
            withBuildIdentifier()
        }
    }
}

通过上述更改,生成的 Gradle 模块元数据文件将始终不同,从而强制下游任务将其视为过期。

禁用 Gradle 模块元数据发布

在某些情况下,您可能希望禁用 Gradle 模块元数据的发布:

  • 您上传到的仓库拒绝该元数据文件(格式未知)

  • 您正在使用 Maven 或 Ivy 特有的概念,这些概念无法正确映射到 Gradle 模块元数据

在这种情况下,禁用 Gradle 模块元数据的发布只需禁用生成元数据文件的任务即可

build.gradle.kts
tasks.withType<GenerateModuleMetadata> {
    enabled = false
}
build.gradle
tasks.withType(GenerateModuleMetadata) {
    enabled = false
}