如何避免Gradle多模块项目中多余的configuration.all属性声明?

问题描述 投票:0回答:1

我正在开发一个 Gradle 多模块项目,其中服务 A(库模块)依赖于最新版本的 Guava (33.1.0-jre)。为了确保 Guava 功能正常,服务 A 的 build.gradle 包含以下属性:

configurations.all {
    attributes {
        attribute(Attribute.of("org.gradle.jvm.environment", String::class.java), "standard-jvm")
    }
}

但是,当服务 B(在服务 A 的 build.gradle 中具有实现)的 build.gradle 中缺少这些属性时,会遇到解析错误。该错误消息表明,由于缺少 org.gradle.jvm.environment 属性,Gradle 无法在 Guava 的不兼容变体之间进行选择。

* What went wrong:
Execution failed for task ':B:compileKotlin'.
> Could not resolve all files for configuration ':B:compileClasspath'.
   > Could not resolve com.google.guava:guava:33.1.0-jre.
     Required by:
         project :police-agency-information-client
      > The consumer was configured to find an API of a library compatible with Java 8, preferably in the form of class files, and its dependencies declared externally, as well as attribute 'org.gradle.jvm.environment' with value 'standard-jvm'. However we cannot choose between the following variants of com.google.guava:guava:33.1.0-jre:
          - androidApiElements
          - jreApiElements
        All of them match the consumer attributes:
          - Variant 'androidApiElements' capabilities com.google.collections:google-collections:33.1.0-jre and com.google.guava:guava:33.1.0-jre declares an API of a library compatible with Java 8, packaged as a jar, and its dependencies declared externally:
              - Unmatched attributes:
                  - Provides attribute 'org.gradle.jvm.environment' with value 'android' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
                  - Doesn't say anything about org.jetbrains.kotlin.platform.type (required 'jvm')
          - Variant 'jreApiElements' capabilities com.google.collections:google-collections:33.1.0-jre and com.google.guava:guava:33.1.0-jre declares an API of  a library compatible with Java 8, packaged as a jar, and its dependencies declared externally:
              - Unmatched attributes:
                  - Provides attribute 'org.gradle.jvm.environment' with value 'standard-jvm' but the consumer didn't ask for it
                  - Provides release status but the consumer didn't ask for it
                  - Doesn'compatibility  say anything about org.jetbrains.kotlin.platform.type (required 'jvm')

有没有办法将这个

attribute(attribute(Attribute.of("org.gradle.jvm.environment", String::class.java), "standard-jvm"))
从服务A继承或传播到服务B,从而避免在模块B的build.gradle文件中重复它们?

我只想在服务 B 中实现服务 A,而不需要任何附加属性等。

如果无法继承,建议采用哪些方法来确保多模块 Gradle 项目中模块之间的配置一致?

java spring kotlin gradle guava
1个回答
0
投票

有几点需要完全明确:

  • 当您将 Guava 声明为
    Service A
    的直接依赖项时,Gradle 在构建
    Service A
    时会查看
    Configuration
    Service A 对象
    1
    的设置。
  • 当您将
    Service A
    声明为
    Service B
    的直接依赖项时,Guava 就成为
    Service B
    的传递依赖项。
    Service B
    负责获取 Guava,Gradle 在构建
    Service B
    时会查找
    Configuration
    Service B
    对象。

基本上有三种方法可以解决这个问题:

  • 建议的方法是在每个项目中应用一个插件,该插件会使用正确的属性设置该项目的
    Configuration
    对象,以获取正确的库版本(在本例中为 Guava)。在任何情况下通常都需要这样的插件来编写和编译代码。 Java 插件Kotlin JVM 插件 可以为您完成此操作。
  • 您“手动”添加属性,就像您目前所做的那样2。如有必要,您可以将此类代码添加到您自己的约定插件中,以便更轻松地在您的项目中共享它。
  • 您在 Service A 中创建了一个“
    fat JAR
    ”,它将
    Service A
    的依赖项打包在一起,因此
    Service B
    不必自行解决它们。不建议这样做。

就您而言,您似乎正在 JVM 上使用 Kotlin 进行开发。因此,我建议您在

Service B
中应用 Kotlin JVM 插件,以便 Gradle 知道在
Service B
中下载哪种风格的 Guava。我承认,尽管我不确定您如何在该项目中编写代码并声明依赖项,但尚未这样做。


1

Configuration
是 Gradle 概念。
implementation
是由 Java 插件(以及通过应用 Java 插件实现此目的的 Kotlin JVM 插件)添加的
Configuration

2 不过,我认为目前在

Service A
中这没有必要,因为您正在使用 Kotlin JVM 插件

© www.soinside.com 2019 - 2024. All rights reserved.