maven 的子模块依赖规则无法传导到父模块? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
abcbuzhiming
V2EX    Java

maven 的子模块依赖规则无法传导到父模块?

  •  
  •   abcbuzhiming 288 天前 1891 次点击
    这是一个创建于 288 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近实践中遇到了依赖冲突,在解决中无意中发现了下面这样奇怪的现象。

    问题一,项目主要靠 spring 启动,项目有两个模块,刚开始的时候,二者的 pom.xml 文件设置如下
    moudle-A
    |--moudle-B


    moudle-B
    |--lib1

    moudle-A 已经在依赖中添加了 moudle-B 。
    moudle-B 依赖 lib1 ,且 moudle 某个 service 在被 spring 初始化的时候,有一个 @PostConstruct 操作,这个操作会调用 lib1 中的类。

    问题现象,程序的启动入口在 moudle-A 中,一旦启动,就报在初始化那个 service 时找不到 lib1 中的类,项目跑不起来。解决办法很简单,把 moudle-A 的依赖改一下,改成下面这样:
    moudle-A
    |--moudle-B
    |--lib1

    就可以了。
    我的疑惑是 moudle-B 依赖 lib1 的这点无法传导给 moudle-A 吗? maven 的依赖规则是严格的按照 pom.xml 文件为单位隔离的吗?



    问题二:还是两个模块
    moudle-A
    |--moudle-B


    moudle-B
    |--lib1
    ----|--lib3 v1 (隐式依赖)
    |--lib2
    |--lib3 v2

    moudle-B 的 pom.xml 显式的依赖 lib1 ,lib2 ,lib3 v2 。
    lib2 拆包分析,自身没有定义依赖,但是需要 lib3 v2 才能运行起来。
    但是 lib1 自身依赖一个 lib3 v1 版本,于是就和 lib3 v2 冲突了。于是我只能编辑 moudle-B 的 pom.xml ,在 lib1 的依赖下显式的把 lib3 v1 给排除掉,像下面这样
    <dependency>
    <groupId>com.xxx</groupId>
    <artifactId>lib1</artifactId>
    <exclusions>
    <exclusion>
    <artifactId>lib3</artifactId>
    <groupId>com.yyy</groupId>
    </exclusion>
    </exclusions>
    </dependency>

    结果程序跑不起来,检查发现程序仍然在使用在使用 lib3 v1 版本,导致 lib2 无法启动,排除无效。后来用 maven 分析了一下,发现问题居然出现在 moudle-A ,moudle-A 引用 moudle-B 的时候,居然还是认为需要依赖 lib3 v1 。最后我没办法,我在 moudle-A 引用 moudle-B 的地方,把 lib3 排除掉了,然后自己加个新的 lib3.就像下面这样
    <dependency>
    <groupId>com.xxx</groupId>
    <artifactId>module-B</artifactId>
    <exclusions>
    <exclusion>
    <artifactId>lib3</artifactId>
    <groupId>com.yyy</groupId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>com.yyy</groupId>
    <artifactId>lib3</artifactId>
    <version>v2</version>
    </dependency>

    问题是解决了,但是这个方法真的是最佳方法吗?而且问题还是和第一个一样,maven 的父模块,是不检查子模块 pom.xml 文件内容的吗?子模块对依赖的一些定义设置,无法传导到父模块?
    8 条回复    2024-12-27 00:03:03 +08:00
    wxw752
        1
    wxw752  
       287 天前
    1. 你那个 module-B 在引入 lib1 的时候,scope 怎么写的? 是不是写了<scope>provided</scope>

    2. 两种可能,maven clean 一下试试,怀疑是 module-a 引用了 module-b 的缓存。第二种可能,module-a 里面除了 module-b 引用过 lib3 v1 ,还有其他包也依赖 lib3 v1 ,maven 依赖树中找到的最近版本是 v1 。
    不过可以肯定的是,那么写绝对不正常
    miaotaizi
        2
    miaotaizi  
       287 天前
    你要不把你的 pom.xml 复制给 ai 让 ai 帮你看看?

    按照你标题的描述我觉得能起作用才怪了。子模块里面的依赖为什么父模块要知道? 反过来, 父模块的依赖一定是能被子模块使用。
    PolarisY
        3
    PolarisY  
       287 天前   1
    给你介绍个命令 mvn dependency:tree -Dverbose ,用用看你能发现什么。
    shangfabao
        4
    shangfabao  
       287 天前
    你把
    moudle-B 的引用贴出来
    helloworld19
        5
    helloworld19  
       287 天前
    abcbuzhiming
        6
    abcbuzhiming  
    OP
       287 天前
    @wxw752
    1.没有写过这个 scope
    2.后面发现。还真是这个原因。


    @miaotaizi
    按照 maven 官方文档的说法,子模块的依赖是会传导进父模块的,所以父模块肯定知道子模块的依赖


    @PolarisY
    感谢你的这个命令,我是思维定式了,被困在 IDEA 这个 IDE 里提供的 maven help 提供的信息中。正是这个命令,让我发现了一件有趣的事情:
    +- (com.squareup.okhttp3:okhttp:jar:3.14.9:compile - version managed from 3.12.13; omitted for duplicate)
    明明,lib1 依赖的 okhttp 是 3.12.13 ,但是运行 mvn dependency:tree 后,显示 compile 时的依赖却是 3.14.9 。很显然,我原本以为这个依赖是 lib1 造成的,现在看 lib1 虽然要引用依 okhttp ,但是版本却不是它指定的。
    最后我顺藤摸瓜的找到了一个命令
    mvn help:effective-pom -Dverbose
    这个命令指出,module A 引用的另外一个 lib ,这个 lib 中,指定了 okhttp:jar:3.14.9 ,根据 maven 依赖冲突调解路径最近原则,maven 实际用了这个版本。

    所以,module B 不需要排除依赖,直接在 module A 中强制指定 okhttp 为 4.x ,根据路径最近原则,这个版本会强行覆盖 module B 中的 okhttp 依赖,于是问题终于解决了
    PolarisY
        7
    PolarisY  
       286 天前
    @abcbuzhiming 解决了明白了就好。不过用「排除」或「显式重写依赖」来解决版本问题不是正道,麻烦且会污染「排除」和「依赖」的语义。
    一般会建议在「根模块」使用 dependencyManagement 来统一管理版本,各子模块只要「按需引用」不再需要关注版本,不再需要「指定版本」或「排除内部引用」等方法解决版本问题。如果遇到深度内部引用的包有冲突,也只需要在「根模块」的 dependencyManagement 中指定该包的版本即可。
    abcbuzhiming
        8
    abcbuzhiming  
    OP
       286 天前
    @PolarisY 非常感谢给出最佳实践方案
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3523 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 10:25 PVG 18:25 LAX 03:25 JFK 06:25
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86