【问题标题】:Which Maven BOM determines a dependency's version in Gradle 5?哪个 Maven BOM 确定 Gradle 5 中的依赖项版本?
【发布时间】:2019-07-23 05:49:38
【问题描述】:

我目前正在开发一个 Gradle 5 项目,该项目导入两个不同的 Maven BOM。因此,我使用没有依赖管理插件的原生 Gradle 语法。但是,两个 BOM 可能会为相同的依赖项定义不同的版本。

dependencies {
    implementation platform ("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}")
    implementation platform ("com.organisation:xyz:${otherBomVersion}")
}

据我所知,在 Maven 中,为给定依赖项定义版本的第一个 BOM 决定了它。相反,在Gradle dependency management plugin 中,为给定依赖项定义版本的最后一个 BOM 决定了它。

在纯 Gradle 5 中导入 BOM 的顺序是如何处理的?

【问题讨论】:

    标签: gradle dependency-management gradle-dependencies maven-bom


    【解决方案1】:

    在 Gradle 中,BOM 的顺序或声明依赖项的位置根本不重要。与使用nearest first 方法的 Maven 不同,Gradle 会考虑所有依赖信息并选择最高的。 documentation 状态

    Gradle 将考虑 所有 请求的版本,无论它们出现在依赖关系图中的什么位置。在这些版本中,它将选择最高的一个。

    一个实际的例子。以下声明将始终选择由 spring-cloud-dependencies BOM 版本 Hoxton.SR8 定义的 Spring Cloud Gateway 的 2.2.5.RELEASE,无论哪个 platform() 声明首先列出:

    dependencies {
        implementation platform('org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8')
        implementation platform('org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR6')
        
        implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    }
    

    dependency insight report 可能如下所示:

    > gradlew -q dependencyInsight --dependency spring-cloud-starter-gateway
    org.springframework.cloud:spring-cloud-starter-gateway:2.2.5.RELEASE (by constraint)
       variant "compile" [
          org.gradle.status              = release (not requested)
          org.gradle.usage               = java-api
          org.gradle.libraryelements     = jar (compatible with: classes)
          org.gradle.category            = library (not requested)
    
          Requested attributes not found in the selected variant:
             org.gradle.dependency.bundling = external
             org.gradle.jvm.version         = 8
       ]
    
    org.springframework.cloud:spring-cloud-starter-gateway:2.2.5.RELEASE
    \--- org.springframework.cloud:spring-cloud-dependencies:Hoxton.SR8
         \--- compileClasspath
    
    org.springframework.cloud:spring-cloud-starter-gateway -> 2.2.5.RELEASE
    \--- compileClasspath
    

    如果您更喜欢来自特定 BOM 的版本,您可以使用 enforcedPlatform()

    【讨论】:

    • 做了一些挖掘以确定这是否/如何适用于平台依赖项,因为它们强制版本而不是标准的传递“最高版本获胜”。这解释了它:docs.gradle.org/current/userguide/…。 “此平台表示法...默认设置 endorseStrictVersions 行为”。 “严格”表示“任何与此版本符号不匹配的版本都将被排除在外”。每个平台都将自己的版本列入白名单,因此任何一个都是合法的选择。然后“最高版本获胜”将接管。
    • 请注意,当使用 mavenBomSpring dependency management plugin 而不是 Gradle 5 的 platform 依赖项时,情况并非如此。在这种情况下,最后一个声明依赖关系的 BOM 获胜。 "如果多个 bom 为同一个依赖提供依赖管理,则将使用最后一个 bom 的依赖管理。"
    【解决方案2】:

    一个更简单的建议是使用Spring Boot Gradle Plugin 文档中描述的这种机制,您可以显式覆盖通过设置属性选择的版本。

    他们给出的例子:

    ext['slf4j.version'] = '1.7.20'
    

    您可以设置的属性的完整列表可以在Spring Boot reference documentation 中找到。

    最终,您将有一种明确的方式来覆盖 Spring Boot 给出的默认值。

    啊,现在我看到你实际上并没有使用那个插件,所以这个机制不适用于你。好吧,如果您开始使用它,上述内容应该可以按预期工作并且是可预测的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-03
      • 2023-04-11
      相关资源
      最近更新 更多