Gradle 复合构建,传递依赖未解决
Gradle Composite Build, transitive dependency is not resolved
首先,很抱歉我必须用伪代码来展示问题,因为原始库代码是封闭源代码,整个构建过程稍微复杂一些。
问题如下:
我们有一个项目A,它使用了一个内部库B。这个库使用了几个开源库,我们暂时称它们为C和D。
出于调试目的,我想创建项目 A 的 gradle 复合构建,其中包括使用 includeBuild
.[=17= 的库 B ]
项目 A:settings.gradle
rootProject.name = 'A'
includeBuild '../B'
并且项目 A 在其 build.gradle 中包含库 B:
repositories {
mavenCentral()
}
dependencies {
compile group: 'bgroup', name: 'b', version: '1.0'
}
库 B 有 C 和 D 作为依赖项。 D有自己的仓库,C在MavenCentral上。
图书馆 B build.gradle:
repositories {
maven {
url "http://D-Repository/maven"
}
mavenCentral()
}
dependencies {
compile group: 'dgroup', name: 'd', version: '1.0'
compile group: 'cgroup', name: 'c', version: '1.6'
}
我可以使用它的 build.gradle 文件编译库 B 而没有问题。
但是当我尝试编译项目 A 的复合版本时,它说:
Could not find dgroup:d:1.0
我解析库 C,但不解析 D。我必须将 D 的存储库添加到项目 A 的 build.gradle 文件中才能使其工作。
项目 A 包括 D 的存储库 build.gradle:
repositories {
maven {
url "http://D-Repository/maven"
}
mavenCentral()
}
dependencies {
compile group: 'bgroup', name: 'b', version: '1.0'
}
所以我必须添加 D 的存储库,即使 A 没有直接将其用作依赖项。
- 这是预期的行为吗?
- 我是不是少了什么配置?
如果我只是从我们自己的存储库中获取库 B(没有复合构建),我不必将 D 的存储库添加到项目 A。但是这样我就无法在处理项目 A 时调试 B。
正如在评论中发现的那样,您发布的 B 是一个包含依赖项 类 的胖 JAR。如果您使用复合构建,则正常的传递依赖解析将按原样使用。使用胖 JAR 作为依赖项是非常糟糕的做法。
如果您现在依赖 fat JAR 的复合构建替换,您有适当的依赖声明,但 A 找不到 D,因为它在它知道的任何存储库中都找不到。您要么必须将对 B 的依赖性替换为包含的构建中的胖 JAR,要么切换为使用正确的传递依赖性处理它的含义。这将涉及发布正常的 B JAR,但使用声明其依赖项的正确元数据并将特定于 D 的存储库添加到 A,以便它可以解析传递依赖项。
首先,很抱歉我必须用伪代码来展示问题,因为原始库代码是封闭源代码,整个构建过程稍微复杂一些。
问题如下:
我们有一个项目A,它使用了一个内部库B。这个库使用了几个开源库,我们暂时称它们为C和D。
出于调试目的,我想创建项目 A 的 gradle 复合构建,其中包括使用 includeBuild
.[=17= 的库 B ]
项目 A:settings.gradle
rootProject.name = 'A'
includeBuild '../B'
并且项目 A 在其 build.gradle 中包含库 B:
repositories {
mavenCentral()
}
dependencies {
compile group: 'bgroup', name: 'b', version: '1.0'
}
库 B 有 C 和 D 作为依赖项。 D有自己的仓库,C在MavenCentral上。
图书馆 B build.gradle:
repositories {
maven {
url "http://D-Repository/maven"
}
mavenCentral()
}
dependencies {
compile group: 'dgroup', name: 'd', version: '1.0'
compile group: 'cgroup', name: 'c', version: '1.6'
}
我可以使用它的 build.gradle 文件编译库 B 而没有问题。 但是当我尝试编译项目 A 的复合版本时,它说:
Could not find dgroup:d:1.0
我解析库 C,但不解析 D。我必须将 D 的存储库添加到项目 A 的 build.gradle 文件中才能使其工作。
项目 A 包括 D 的存储库 build.gradle:
repositories {
maven {
url "http://D-Repository/maven"
}
mavenCentral()
}
dependencies {
compile group: 'bgroup', name: 'b', version: '1.0'
}
所以我必须添加 D 的存储库,即使 A 没有直接将其用作依赖项。
- 这是预期的行为吗?
- 我是不是少了什么配置?
如果我只是从我们自己的存储库中获取库 B(没有复合构建),我不必将 D 的存储库添加到项目 A。但是这样我就无法在处理项目 A 时调试 B。
正如在评论中发现的那样,您发布的 B 是一个包含依赖项 类 的胖 JAR。如果您使用复合构建,则正常的传递依赖解析将按原样使用。使用胖 JAR 作为依赖项是非常糟糕的做法。
如果您现在依赖 fat JAR 的复合构建替换,您有适当的依赖声明,但 A 找不到 D,因为它在它知道的任何存储库中都找不到。您要么必须将对 B 的依赖性替换为包含的构建中的胖 JAR,要么切换为使用正确的传递依赖性处理它的含义。这将涉及发布正常的 B JAR,但使用声明其依赖项的正确元数据并将特定于 D 的存储库添加到 A,以便它可以解析传递依赖项。