Gradle依赖管理 - 传递依赖版本不正确

4
我有两个在IntelliJ IDEA 2016中编辑的项目,它们都使用Gradle依赖管理:项目A和项目B。
项目A定义了一个编译范围的elasticsearch依赖项:
    compile 'org.elasticsearch:elasticsearch:2.3.1'

项目B声明了对项目A的编译范围依赖,如下所示:
    compile 'com.mycompany:elasticsearch-common:2.3.1'

我期望在IntelliJ IDEA 2016的Gradle工具窗口中,项目B能够看到:
...
com.mycompany:elasticsearch-common:2.3.1 (Compile)
    org.elasticsearch:elasticsearch:2.3.1 (Compile)
...

我看到的是:
...
com.mycompany:elasticsearch-common:2.3.1 (Compile)
    org.elasticsearch:elasticsearch:1.5.2 (Compile)
...

项目B中没有其他依赖项依赖于elasticsearch,因此它没有被另一个依赖声明覆盖。
实际上,我们在项目A的nexus上的pom.xml中有这个:
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>2.3.1</version>
    <scope>compile</scope>
</dependency>

为什么IntelliJ报告elasticsearch的传递版本为1.5.2?
我尝试过:
1. 删除项目B目录中的.idea和.gradle 2. 删除gradle缓存 3. 在IntelliJ中使缓存失效并重新启动 4. 发誓 5. 大量饮茶 6. 向朋友和同事询问 7. 给Oprah发电子邮件 8. 回到当一切正常时使用的IntelliJ 15(现在不再是这样) 9. 去厕所(与5有关),希望我回来时它会神奇地自己修复
上述所有方法都无效。
指定在项目B中具体依赖于elasticsearch:2.3.1可以解决问题,但这不是传递依赖的原因吗?
感谢任何帮助。
更新1: 如LanceJava在评论中建议的那样,我运行了gradle dependencies以查看发生了什么。
这表明它正在特定地降级它:
org.elasticsearch:elasticsearch:2.3.1 -> 1.5.2

当我在该依赖上运行 gradle dependencyInsight 命令时,它显示如下结果:
:dependencyInsight
com.mycompany:elasticsearch-common:2.3.1 (selected by rule)
\--- compile

org.elasticsearch:elasticsearch:1.5.2 (selected by rule)

org.elasticsearch:elasticsearch:2.3.1 -> 1.5.2
\--- com.mycompany:elasticsearch-common:2.3.1
     \--- compile

有人知道为什么会出现这种情况吗?
更新2 看起来这个帖子里提供了答案:https://discuss.gradle.org/t/excluded-dependence-comes-back-when-spring-boot-plugin-is-applied/17945/2 似乎 Gradle 的 Spring Boot 插件喜欢介入一些事情并强制使用自己的依赖版本(即使我没有使用使用 Spring Data 的 spring-boot-starter)。
我通过添加以下内容来解决这个问题:
ext[elasticsearch.version] = '2.3.1'

添加到我的 build.gradle 文件中。

1
尝试从命令行运行 gradle dependencies 命令。它应该会告诉你发生了什么。也许有一个自定义的 ResolutionStrategy - lance-java
@LanceJava 谢谢!我这样做了,看起来它是在特定地降级: org.elasticsearch:elasticsearch:2.3.1 -> 1.5.2当我执行dependencyInsight时,它显示为: org.elasticsearch:elasticsearch:1.5.2(由规则选择)org.elasticsearch:elasticsearch:2.3.1 -> 1.5.2 --- com.mycompany:elasticsearch-common:2.3.1 --- runtime - ndtreviv
@LanceJava 请查看更新。 - ndtreviv
1个回答

4
问题中没有明确说明,这个项目使用了 spring-boot gradle插件,强制规定库的某些版本,并且强制将我的elasicsearch版本降级以保持其与spring-data要求的一致性(尽管我没有在项目中使用spring-data)。
我通过执行以下命令发现了这一点:
gradle dependencyInsight --dependency elasticsearch --configuration compile

当时的结果如下:

org.elasticsearch:elasticsearch:1.5.2 (selected by rule) 

org.elasticsearch:elasticsearch:2.3.1 -> 1.5.2 
   \--- com.mycompany:elasticsearch-common:2.3.1 
       \--- runtime

我了解到(selected by rule)的意思是有程序自动选择了那个特定版本。这缩小了范围,说明它是一个插件。
我只使用了4个插件,分别是:
  1. java
  2. maven
  3. idea
  4. spring-boot
而我之前从未在其他地方使用过spring-boot插件(因此也没有遇到过此问题)。
一旦我注释掉了这个插件,我就可以看到依赖关系是正确的。
此时,我了解到需要通过明确指定我想要使用的版本来解决问题:
ext[elasticsearch.version] = '2.3.1'

排序完成。再来一杯茶给我!


1
兄弟,感谢你抽出时间写下这个问答,我也曾经被同样的问题困扰,终于在这里找到了解救之道! - Michal Hosala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接