我正在将Maven库项目迁移到Gradle。原始项目还具有可选的依赖项。我使用 java 库插件,但将以前可选的依赖项移动到实现会导致运行时依赖项而不是编译。所以我尝试了 gradle 功能变体,这会导致pom.xml
中的正确依赖项。但是这样做的结果是测试编译失败,因为测试编译类路径上缺少功能变体的依赖项!
这是我目前在build.gradle
中的设置:
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'maven-publish'
sourceCompatibility = 1.8
java {
registerFeature('oSupport') {
usingSourceSet(sourceSets.main)
}
}
dependencies {
api 'my.compile:dep-a:1.0.0'
implementation 'my.runtime:dep-i:1.0.0'
oSupportApi 'my.optional:dep-o:1.0.0'
}
假设有一个类O
可从my.optional:dep-o
.如果我在src/main/java
的任何类中导入O
,它可以完美运行。此外,依赖项将直接导出到 Maven(使用gradle generatePomFileForMavenJavaPublication
,请参阅下面生成的pom.xml
中的依赖项(。但是任何使用类O
src/test/java
测试都不会编译(import my.optional.O;
创建error: package my.optional does not exist
(
<dependencies>
<dependency>
<groupId>my.compile</groupId>
<artifactId>dep-a</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>my.rintime</groupId>
<artifactId>dep-r</artifactId>
<version>1.0.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>my.optional</groupId>
<artifactId>dep-0</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
如何解决这个问题?我知道我本可以使用 nebula.optional-base 插件而不是内置的 Gradle 功能变体,但我更喜欢新的 gradle 内置支持可选依赖项。
PS:我使用 Java 8 和 Gradle 5.6.2
当功能源集使用主源集时,这看起来像一个错误。你能报告 https://github.com/gradle/gradle/issues 吗?
同时,这应该可以解决它:
configurations {
testCompileClasspath.extendsFrom(oSupportApi)
testRuntimeClasspath.extendsFrom(oSupportApi)
testRuntimeClasspath.extendsFrom(oSupportImplementation)
}
真的很奇怪,我同意@melix这似乎是一个 Gradle 错误。
恕我直言,以下内容将修复它,但不需要:
dependencies {
api 'my.compile:dep-a:1.0.0'
implementation 'my.runtime:dep-i:1.0.0'
oSupportApi 'my.optional:dep-o:1.0.0'
testImplementation(project(":${project.name}")) {
capabilities {
requireCapability("${project.group}:${project.name}-o-support")
}
}
}
对于这种只有一个功能的简化设置,依赖项可以替换为testImplementation 'my.optional:dep-o:1.0.0'
但对于一般较大的依赖项列表,此方法避免了重复依赖项作为@melixextendsFrom
解决方案。