英文:
Why gradle resolve dependencies in the module name order by default?
问题
我有三个模块:
amodule
bmodule
cmodule
这三个模块都有集成测试。bmodule
是基础模块,其中包含我想在 amodule
和 cmodule
的集成测试中使用的 BaseClass
。
我项目的示例位于 GitHub 上:https://github.com/ljql/test-deps
我尝试在 amodule
和 cmodule
的集成测试中添加对 bmodule
的依赖。
build.gradle
文件在 amodule
和 cmodule
模块中看起来相同:
sourceSets {
intTest {
java {
srcDir 'src/test-integration/java'
}
resources {
srcDir 'src/test-integration/resources'
}
compileClasspath += rootProject.project(':bmodule').sourceSets.intTest.output
runtimeClasspath += rootProject.project(':bmodule').sourceSets.intTest.output
}
}
configurations {
intTestCompile {
extendsFrom compile
}
intTestRuntime {
extendsFrom runtime
}
}
dependencies {
intTestCompile project(path: ':bmodule', configuration: 'intTestCompile')
}
但是当我尝试构建 amodule
时,我遇到了一个错误:
Build file '/test-deps/amodule/build.gradle' line: 10
A problem occurred evaluating project ':amodule'.
> Could not get unknown property 'intTest' for SourceSet container of type org.gradle.api.internal.tasks.DefaultSourceSetContainer.
cmodule
的构建(它是 amodule
的副本)成功完成。
amodule
和 cmodule
之间唯一的区别是它们的名称。amodule
位于 bmodule
之前,而 cmodule
位于 bmodule
之后。
在我的情况下,我如何指定 Gradle 解析依赖项的顺序?我希望 Gradle 首先了解 bmodule
,然后再了解 amodule
和 cmodule
。
英文:
I've got three modules:
amodule
bmodule
cmodule
There are integration-tests in all of these three modules. The bmodule
is the base - it contains BaseClass
, which I want to use in integration-tests in amodule
and cmodule
The example of my project is on github: https://github.com/ljql/test-deps
I try to add dependency to integration-tests of bmodule
in amodule
and cmodule
.
File build.gradle
looks the same in modules amodule
and cmodule
sourceSets {
intTest {
java {
srcDir 'src/test-integration/java'
}
resources {
srcDir 'src/test-integration/resources'
}
compileClasspath += rootProject.project('bmodule').sourceSets.intTest.output
runtimeClasspath += rootProject.project('bmodule').sourceSets.intTest.output
}
}
configurations {
intTestCompile {
extendsFrom compile
}
intTestRuntime {
extendsFrom runtime
}
}
dependencies {
intTestCompile project(path: ':bmodule', configuration: 'intTestCompile')
}
But when I try to build amodule
I've got an error:
Build file '/test-deps/amodule/build.gradle' line: 10
A problem occurred evaluating project ':amodule'.
> Could not get unknown property 'intTest' for SourceSet container of type org.gradle.api.internal.tasks.DefaultSourceSetContainer.
The build of cmodule
, which is the copy of amodule
, is completed successfully.
The only difference between amodule
and cmodule
is in their names. The amodule
precedes the bmodule
and the cmodule
followed by the bmodule
How can I specify a sequence of gradle resolve dependencies in my case? I want gradle to find out about the bmodule
first and then about the amodule
and the cmodule
答案1
得分: 0
尝试将以下内容放入您的 amdoule
模块的 build.gradle
文件中:
preBuild.dependsOn ":bmodule:build"
英文:
Try putting this in the your amdoule
's build.gradle
preBuild.dependsOn ":bmodule:build"
答案2
得分: 0
你面临着一个项目评估排序的问题。由于amodule
和cmodule
都期望找到bmodule
的特定组件,你需要请求Gradle确保先评估bmodule
。
你可以在amodule
和cmodule
的构建文件中添加以下内容:
evaluationDependsOn(':bmodule')
虽然Gradle提供了一个API来解决这个问题,但只有在没有循环依赖的情况下才能正常工作,也就是说bmodule
不能依赖于amodule
或cmodule
,否则你将无法通过这种方式找到解决方案。
另一种方法是利用适当的依赖解析,并声明你希望通过将它们暴露为测试固件来共享一些测试类,例如。
英文:
You have a project evaluation ordering problem. Since both amodule
and cmodule
expect to find specific components of bmodule
, you need to ask Gradle to make sure bmodule
has been evaluated first.
You can add in the build files of amodule
and cmodule
the following:
evaluationDependsOn(':bmodule')
While Gradle offers an API to resolve this, it will only work if you have no cycle, that is bmodule
does not have dependencies on either amodule
or cmodule
, otherwise you will not be able to find a solution this way.
Another approach would be to leverage proper dependency resolution and declare that you want to share some test classes by having them exposed as test-fixtures for example.
答案3
得分: 0
Gradle有三个构建阶段:
- 初始化
- 配置
- 执行
但只有当Gradle完成了这三个阶段时,才会显示解析所有依赖项的最终结果。
错误指示了sourceSets中的一个字符串 - 它来自配置阶段。在这个阶段开始时,Gradle对所有模块中的任何配置一无所知。Gradle会按顺序逐个模块地了解每个模块的内容。当Gradle首次考虑amodule
的配置时,它对bmudule
中的任何配置一无所知。
在问题中,我想要在配置:amodule:intTest
中定义compileClasspath
和runtimeClasspath
,但我也可以在自定义任务中定义它,没有什么可以阻止我这样做。Gradle将在第三阶段执行它,最终的compileClasspath
和runtimeClasspath
将包含来自bmodule:intTest
的信息。
amodule
的build.gradle
结果:
sourceSets {
intTest {
java {
srcDir 'src/test-integration/java'
}
resources {
srcDir 'src/test-integration/resources'
}
}
}
configurations {
intTestCompile {
extendsFrom compile
}
intTestRuntime {
extendsFrom runtime
}
}
task intTest {
sourceSets.intTest.compileClasspath += rootProject.project('bmodule').sourceSets.intTest.output
sourceSets.intTest.runtimeClasspath += rootProject.project('bmodule').sourceSets.intTest.output
}
英文:
Gradle has three build phases:
- Initialization
- Configuration
- Execution
But the final result of resolving all dependencies appears only when gradle completes all three phases.
The error indicates a string in sourceSets - it is from the phase Configuration. At the start of this phase gradle knows nothing about any configurations in all modules. And gradle learns about the content of each module sequentially module-by-module. Of course when gradle considers the configuration of the amodule
for the first time, it doesn't know anything about any configurations in the bmudule
.
In the question I want to define compileClasspath and runtimeClasspath in confuguration :amodule:intTest
. But there is nothing to stop me to define it in a custom task. Gradle will execute it on the third phase and the final compileClasspath and runtimeClasspath will contain the information from the bmodule:intTest
The result build.gradle of amodule
:
sourceSets {
intTest {
java {
srcDir 'src/test-integration/java'
}
resources {
srcDir 'src/test-integration/resources'
}
}
}
configurations {
intTestCompile {
extendsFrom compile
}
intTestRuntime {
extendsFrom runtime
}
}
task intTest {
sourceSets.intTest.compileClasspath += rootProject.project('bmodule').sourceSets.intTest.output
sourceSets.intTest.runtimeClasspath += rootProject.project('bmodule').sourceSets.intTest.output
}
专注分享java语言的经验与见解,让所有开发者获益!
评论