maven依赖包版本冲突小尝试

1 篇文章 0 订阅

冲突1

项目Demo1依赖于Y、Z依赖包,Y依赖于A,Z依赖于A、B、C,故项目Demo1最终依赖于Y、Z、A、B、C。但是Y依赖于A的1.x版本,Z依赖于A的2.x版本,这时候就出现依赖包冲突。

世界原是美好的。存在有些依赖包,版本更新的改动小,不会影响使用,即加载哪个版本的依赖包都不影响项目。像log4j日志系列某一批版本畅通无阻,当然不同日志系列一起引用仍有可能存在问题(比如log4j和logback一起,虽然是同一个创始人)

if(A的2.x向下兼容1.x) 只需要保留2.x版本,exclude掉Y依赖的A的版本。

else
1. 寻找Y或者Z可替换的依赖包,直到不冲突
2. 如没有替换依赖包,估计悲剧了。要不修改Y、Z依赖包源码(有提供源码的基础上),要不自己重现实现。

<!--exclude掉Y依赖的A的版本-->
<dependency>
    <groupId>a.b.c</groupId>
    <artifactId>Y</artifactId>
    <version>${Y.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>aa.bb.cc</artifactId>
            <groupId>A</groupId>
        </exclusion>
    </exclusions>
</dependency>

话说,如何有效确认哪些包有冲突?

您需要一个层级树的展示方式。

普通版

主流的IDE已经集成了maven命令,所以层级树的展示不是问题。比如eclipse:
eclipse 依赖包层级树

bigger版

总有那么一些牛x的人,不喜欢用IDE集成开发平台,追求原生态。
他们喜欢直接操作maven命令:mvn dependency:tree
mvn 依赖包层级树

冲突2

SDK是部门业务的基础的依赖包,对接部门主要业务底层,故主要服务都依赖于SDK依赖包。SDK依赖于几十个依赖包,服务S1、S2、S3依赖于SDK,同时依赖于其他依赖包A、B、C…X、Y、Z等。

依赖包多不是问题,问题是其他的依赖包和SDK依赖包有不少交集,有不少交集也不是问题,反正maven会管理,问题是不少交集中有好几个包版本冲突,冲突也不是问题,你还不兼容。。。。。。(好吧,让服务S1、S2、S3负责人改用高版本依赖包,谁让他们用那么老的版本。负责人:TMD,!@¥#……&@!@,这项目是上上上代流传下来的。)

世界原是美好的。印象中,似乎好像也许,maven支持多模块项目的建立。有点意思,虽然不完全符合我们需要的,但是够了。我不需要maven的多模块机制,只需要父模块可以抽取公用的依赖包、插件、maven库、变量属性这个特性。

上述问题是个表面现象。其实部门的项目开发都是多个项目组同时进行,即使可以保证每个项目组组内使用依赖包版本一致,也保证不了整个部门,整个公司。

利用父模块的特性,打算提取一个超级父模块,里面抽取了公用插件、公用maven库、变量属性(项目组或部门或公司所有依赖包版本号,这是个积累的过程,属性名约定俗成为${artifactId}.version。在子模块引用依赖的时候,如果无法引入,那么就是这个依赖包版本不存在父模块,可添加。注意:可能存在artifactId一致,groupid不一样的依赖包,此时需特殊处理),如下父模块pom.xml

    <groupId>x.y.z</groupId>
    <artifactId>project-base</artifactId>
    <version>1.0</version>
    <packaging>pom</packaging>


    <name>project-base</name>
    <url>http://maven.apache.org</url>


    <properties>
        <!-- 编译时的编码 -->
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <!-- 文件拷贝时的编码 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- 依赖包版本 -->
        <aspectjweaver.version>1.8.6</aspectjweaver.version>
        <aspectjrt.version>1.8.6</aspectjrt.version>        

        <commons-beanutils.version>1.9.2</commons-beanutils.version><!-- <groupId>commons-beanutils</groupId> -->
        <commons-codec.version>1.10</commons-codec.version><!-- <artifactId>commons-codec</artifactId> -->
        <commons-lang3.version>3.4</commons-lang3.version><!-- <groupId>org.apache.commons</groupId> -->
        <commons-io.version>2.4</commons-io.version><!-- <groupId>commons-io</groupId> -->

        <gson.version>2.3.1</gson.version><!-- <groupId>com.google.code.gson</groupId> -->
        <guava.version>18.0</guava.version><!-- <groupId>com.google.guava</groupId> -->

        <joda-time.version>2.8.2</joda-time.version><!-- <groupId>joda-time</groupId> -->
        <junit.version>4.12</junit.version><!-- <groupId>junit</groupId> -->

        <log4j.version>1.2.17</log4j.version><!-- <groupId>log4j</groupId> -->

        <spring.version>4.2.0.RELEASE</spring.version><!-- <groupId>org.springframework</groupId> -->
    <properties>
    <repositories>
        <repository>
        ...
        </repository>
    </repositories>
    <build>
        <plugins>
            <plugin>
            ...
            </plugin>
        </plugins>
    </build>

子模块pom.xml

    <parent>
        <artifactId>project-base</artifactId>
        <groupId>x.y.z</groupId>
        <version>1.0</version>
    </parent>
    <groupId>x.y.z.a</groupId>
    <artifactId>S1</artifactId>
    <version>1.0.1</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${gson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons-lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons-io.version}</version>
        </dependency>
    </dependencies>

总结

个人遇到依赖包冲突,一般出现如下几个情景:

  1. 服务启动偶尔报错,偶尔正常(加载顺序导致)
  2. NoClassDefFoundErro
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值