V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yema50
V2EX  ›  Java

[maven 传递依赖问题请教]

  •  
  •   yema50 · 2020-08-12 17:05:28 +08:00 · 2648 次点击
    这是一个创建于 1566 天前的主题,其中的信息可能已经有所发展或是发生改变。

    问题描述:

    项目 A 里间接引入了 springboot-autoconfigure 依赖,autoconfigure 里 spring-data-elasticsearch 的版本是 3.1.5 并且<optional>true</optional>, 然后在该 A 项目里显式引入了 3.2.6 版本的 spring-data-elasticsearch ;

    另一个项目 B 里引入了项目 A 并且也间接引入了 springboot-autoconfigure,此时在项目 B 里的 spring-data-elasticsearch 版本却是 3.1.5. 如果按照最近原则,不是应该优先选择 3.2.6 吗?请教大佬解答

    第 1 条附言  ·  2020-08-12 18:09:50 +08:00

    A项目依赖 B项目依赖

    20 条回复    2020-08-13 17:46:05 +08:00
    hejawy
        1
    hejawy  
       2020-08-12 17:12:46 +08:00
    idea 装个 maven helper 插件看下依赖的情况。另外显示指定版本不香吗,一定要纠结各种依赖导致的版本混乱?
    yema50
        2
    yema50  
    OP
       2020-08-12 17:29:39 +08:00
    @hejawy 嗯,装了 maven helper 插件,在项目 B 里查看 es 依赖来自于项目 A,并且版本是 3.1.5, 然后在项目 A 里查看确实是 3.2.6 。 目前是在 B 项目里显式指定了版本,但因为 A 其实是个公共模块, 所以希望能通过继承使用 A 里面的依赖
    yema50
        3
    yema50  
    OP
       2020-08-12 17:30:26 +08:00
    现在是真心想搞懂这个问题处在哪个地方
    goldpumpkin
        4
    goldpumpkin  
       2020-08-12 17:51:10 +08:00
    会不会是 B 项目引入其他包也有 es 3.1.5
    yema50
        5
    yema50  
    OP
       2020-08-12 17:53:54 +08:00
    @goldpumpkin 嗯,其它依赖里没有的,通过依赖树看过
    bianjp
        6
    bianjp  
       2020-08-12 19:21:21 +08:00
    项目 B 的 POM 继承了 spring-boot-starter-parent 吧?

    * spring-boot-starter-parent 继承了 spring-boot-dependencies
    * spring-boot-dependencies 在其 dependencyManagement 中 import 了 spring-data-releasetrain
    * spring-data-releasetrain 中定义了 spring-data-elasticsearch 的版本号

    简单说来,就是项目 B 的 parent POM 的 dependencyManagement 中定义了 spring-data-elasticsearch 的版本号,这个定义优先级高于传递依赖中定义的版本。
    yema50
        7
    yema50  
    OP
       2020-08-12 19:29:03 +08:00
    @bianjp 感谢回复。 但是我也尝试过在项目 A 里写 dependencyManagement 来限定 es 的版本号,貌似不起作用
    bianjp
        8
    bianjp  
       2020-08-12 19:36:06 +08:00   ❤️ 1
    @yema50 你需要在项目 B 的 dependencyManagement 中定义版本号。项目 A 作为项目 B 的一个普通依赖,其 dependencyManagement 优先级低于项目 B 的 parent POM 。
    AlbertChen
        9
    AlbertChen  
       2020-08-12 19:36:13 +08:00   ❤️ 2
    Dependency mediation - this determines what version of an artifact will be chosen when multiple versions are encountered as dependencies. Maven picks the "nearest definition". That is, it uses the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, the first declaration wins.

    "nearest definition" means that the version used will be the closest one to your project in the tree of dependencies. Consider this tree of dependencies:

    A
    ├── B
    │ └── C
    │ └── D 2.0
    └── E
    └── D 1.0

    In text, dependencies for A, B, and C are defined as A -> B -> C -> D 2.0 and A -> E -> D 1.0, then D 1.0 will be used when building A because the path from A to D through E is shorter.
    AlbertChen
        10
    AlbertChen  
       2020-08-12 19:38:58 +08:00
    312ybj
        11
    312ybj  
       2020-08-12 22:57:14 +08:00 via Android
    springboot 和 es 的版本有限制, 你是不是在微信群里提过这个问题啊。3.2.*的 es 只能用 2.2.*的 springboot
    qwerthhusn
        12
    qwerthhusn  
       2020-08-13 09:53:11 +08:00
    Maven 的依赖确实搞不太懂,之前遇到过,一个 dependency 放在同一个 pom 的 dependencies 里面的上方和下方,最后出现的版本都不一样
    yema50
        13
    yema50  
    OP
       2020-08-13 10:00:22 +08:00
    @AlbertChen 感谢老哥回复。 看了 8 楼大佬的回复,我感觉是我理解错了。moduleB 里没有显示引入 es 依赖, 所以 es 依赖树会是 moduleB -> moduleA -> es 3.2.6. 因为 moduleB 里有间接引入 autoconfigure 的依赖,autoconfigure 里定义了 3.1.5 的 es 依赖但是设置了 optional 为 true, 所以其实这个 autoconfigure 里的依赖并不会传递到 moduleB 里吗?如果 autoconfigure 这个依赖传递进了 moduleB, 按照就近原则应该是 moduleB -> moduleA -> es326 路径更短
    yema50
        14
    yema50  
    OP
       2020-08-13 10:02:04 +08:00
    @312ybj 是的老哥, 我之前在微信群里问过。解决办法是在 moduleB 里显示引入了想要的版本, 但是对这个问题的原因有点没弄懂,所以又来问了一次 哈哈
    yema50
        15
    yema50  
    OP
       2020-08-13 10:03:41 +08:00
    @qwerthhusn 应该是如果有两个不同版本,并且路径深度一致, 会使用先找到的, 所以会出现根据定义的位置的先后 决定使用哪一个
    yema50
        16
    yema50  
    OP
       2020-08-13 10:05:18 +08:00
    @bianjp 感谢老哥解惑
    bianjp
        17
    bianjp  
       2020-08-13 12:46:21 +08:00
    这个问题关键是 dependencyManagement, 不是路径深度。
    yema50
        18
    yema50  
    OP
       2020-08-13 13:11:57 +08:00
    @bianjp 嗯嗯,感觉这个是问题的 root cause 哈哈
    Macolor21
        19
    Macolor21  
       2020-08-13 15:24:16 +08:00 via iPhone
    可以尝试下 gradle,可以用 implemention 隐藏依赖细节,如果需要暴露对外依赖,可以用 api 。
    yema50
        20
    yema50  
    OP
       2020-08-13 17:46:05 +08:00
    @Macolor21 感觉是要学习学习 gradle 了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5603 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 09:14 · PVG 17:14 · LAX 01:14 · JFK 04:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.