我正在开发一个 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 项目中模块之间的配置一致?
有几点需要完全明确:
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 插件 可以为您完成此操作。Service A
中创建了一个“fat JAR”,它将
Service A
的依赖项打包在一起,因此 Service B
不必自行解决它们。不建议这样做。就您而言,您似乎正在 JVM 上使用 Kotlin 进行开发。因此,我建议您在
Service B
中应用 Kotlin JVM 插件,以便 Gradle 知道在 Service B
中下载哪种风格的 Guava。我承认,尽管我不确定您如何在该项目中编写代码并声明依赖项,但尚未这样做。
Configuration
是 Gradle 概念。 implementation
是由 Java 插件(以及通过应用 Java 插件实现此目的的 Kotlin JVM 插件)添加的 Configuration
。
2 不过,我认为目前在
Service A
中这没有必要,因为您正在使用 Kotlin JVM 插件