如何在测试中使用 gradle 特性变量依赖?
How to use gradle feature variant dependecies in tests?
我正在将 Maven 库项目迁移到 Gradle。原始项目也有可选的依赖项。我使用 java-library plugin but moving the formerly optional dependencies to implementation results in runtime dependencies instead of compile. So I tried the gradle feature variants,它在 pom.xml
中产生正确的依赖关系。但是这样做的结果是测试编译失败,因为测试编译 classpath!
上缺少功能变体的依赖项
这是我在 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'
}
假设 my.optional:dep-o
有 class O
。如果我在 src/main/java
中的任何 class 中导入 O
,它会完美运行。此外,依赖项直接导出到 Maven(使用 gradle generatePomFileForMavenJavaPublication
,请参阅下面生成的 pom.xml
中的依赖项)。但是 src/test/java
中使用 class O
的任何测试都不会编译(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:我用的是Java8和Gradle5.6.2
当功能源集使用主源集时,这看起来像是一个错误。你能报告 https://github.com/gradle/gradle/issues 吗?
同时,这应该可以修复它:
configurations {
testCompileClasspath.extendsFrom(oSupportApi)
testRuntimeClasspath.extendsFrom(oSupportApi)
testRuntimeClasspath.extendsFrom(oSupportImplementation)
}
真的很奇怪,我同意@melix 这似乎是 Gradle bug.
以下将修复它,但不需要,恕我直言:
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'
代替,但对于一般较大的依赖项列表,此方法避免重复依赖项,因为 @melix 的 extendsFrom
解决方案。
我正在将 Maven 库项目迁移到 Gradle。原始项目也有可选的依赖项。我使用 java-library plugin but moving the formerly optional dependencies to implementation results in runtime dependencies instead of compile. So I tried the gradle feature variants,它在 pom.xml
中产生正确的依赖关系。但是这样做的结果是测试编译失败,因为测试编译 classpath!
这是我在 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'
}
假设 my.optional:dep-o
有 class O
。如果我在 src/main/java
中的任何 class 中导入 O
,它会完美运行。此外,依赖项直接导出到 Maven(使用 gradle generatePomFileForMavenJavaPublication
,请参阅下面生成的 pom.xml
中的依赖项)。但是 src/test/java
中使用 class O
的任何测试都不会编译(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:我用的是Java8和Gradle5.6.2
当功能源集使用主源集时,这看起来像是一个错误。你能报告 https://github.com/gradle/gradle/issues 吗?
同时,这应该可以修复它:
configurations {
testCompileClasspath.extendsFrom(oSupportApi)
testRuntimeClasspath.extendsFrom(oSupportApi)
testRuntimeClasspath.extendsFrom(oSupportImplementation)
}
真的很奇怪,我同意@melix 这似乎是 Gradle bug.
以下将修复它,但不需要,恕我直言:
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'
代替,但对于一般较大的依赖项列表,此方法避免重复依赖项,因为 @melix 的 extendsFrom
解决方案。