maven jar冲突问题

maven 不同版本jar冲突问题的解决办法

今天想把dubbo整合到项目中,本来项目是框架为ssm的maven项目。在引入dubbo之前项目正常运行。但是在引入dubbo以及zookeeper之后,报了异常。发现是jar包冲突问题,之前遇到过一次没有理会,这次整理一下。
1.maven为什么会发生jar包冲突问题?
maven管理jar是其核心功能之一,maven对于你要引入的jar在解析的时候会把此jar内部依赖的jar同样进行解析,接着会对内部依赖的jar依赖的jar进行解析…….直到不再存在依赖的jar的时候,会把这些jar全部引入。所以我们只需要引入自己需要的jar,而此jar依赖的jar交给maven帮我们找到并引入。减少了我们去寻找其依赖的jar以及找到对应版本这项工作(要知道这项工作是很费时间的)。但是这样也引发了一个问题,就是我们引入的jar所依赖的jar版本可能不同,而Maven在解析pom文件时,对于同一个jar包只会保留一个,这样便避免因引入两个jar包导致的工程运行不稳定的问题。那么留下的那个jar在使用过程中就可能因为版本不通而引发报错,这便是jar冲突问题发生的根源。
2.如何解决此问题。
要想解决就应该注意到Maven在解析pom文件时,对于同一个jar包只会保留一个,而留下的这一个不是我们需要的才会出现意料之外的报错。那么我们就要知道maven是如何决定保留那个jar的。
2.1 在有多个版本的jar依赖时maven是如何决定保留哪个的。
1优先按照依赖管理元素中指定的版本声明,此时下面的两个原则都无效。
2若无版本声明,则按照“短路径优先”的原则,即选择依赖树中路径最短的版本。
3若路径长度一致,则按照“第一声明优先”的原则,即选择POM中最先声明的版本。

下面是我主pom文件中的一些配置,使用的是第一个原则(强烈推荐,因为基本没发生过问题)。
<!--定义此文件使用的全局参数**************开始*****************-->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><!--项目统一字符集,此配置会被maven自动识别而使用,当然也可以在本文件其他位置使用。-->
    <!--下面的这些参数将在本配置文件中作为全局变量使用-->
    <springframework.version>4.2.4.RELEASE</springframework.version><!--spring的版本控制-->
    <atom.version>1.1-SNAPSHOT</atom.version><!--miniUi的版本控制-->
    <cxf.version>3.1.11</cxf.version><!--前端优化框架cxf的版本号-->
  </properties>
  <!--定义此文件使用的全局参数**************结束*****************-->
  <!--推荐引入jar的顺序:前台框架->->->前台优化框架->->->spring框架(包括MVC)->->->mybatis框架->->->
                        一些工具jar(1:测试使用如junit、log,2:任务调度如Quartz、监控,3系统处理标准文档如poi、4调用外部系统如httpclient,Json) -->

  <!--使用dependencyManagement当子项目使用父类引入的jar时:若声明版本号则子项目单独从数据仓库引入jar,若不声明版本号,则使用父类的jar(用来确保引用的jar版本统一)
  并且使用dependencyManagement时,只引入其声明的的jar,但不使dependencyManagement时,子项目会引入所有的父项目jar-->
  <dependencyManagement>
    <!--下面引入整个项目(包括主项目和子项目使用的jar的集合~~这里需要声明版本号来引入jar,而子项目通过继承引用这里的jar)-->
    <dependencies>
    <!--spring begin-->
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>a</artifactId>
        <version>${springframework.version}</version>
      </dependency>
      <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>f</artifactId>
        <version>${springframework.version}</version>
      </dependency>
      <!--spring end-->
      </dependencies>
  </dependencyManagement>
“短路径优先”的原则是指如下(->为依赖):
    比如a.jar->b.jar->c.jar->d.1.0.jar
    而f.jar->g.jar->d.1.3.jar
    那么d.1.3.jar的路径短与d.1.0.jar则保留d.1.3.jar。
“第一声明优先”的原则:
这是在“短路径优先”的原则并未决定出保留哪个的时候生效,即   
    a.jar->b.jar->d.1.0.jar
    f.jar->g.jar->d.1.3.jar
    而在pom中a的声明优先与f的声明那么就保留优先声明的依赖d.1.0.jar。
所以根据这三原则基本可以解决jar冲突问题。当然maven还提供了另一种方式:使用<exclusion>标签。
那就是你可以在声明中手动排除可能导致冲突的依赖jar,例如我排除dubbo中对spring的依赖的方式。
<!-- dubbo begin -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>2.5.7</version>
                <exclusions>
                    <exclusion>
                        <artifactId>spring</artifactId>
                        <groupId>org.springframework</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.2</version>
            </dependency>
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.9</version>
            </dependency>

            <dependency>
                <groupId>org.apache.curator</groupId>
                <artifactId>curator-framework</artifactId>
                <version>2.12.0</version>
            </dependency>
            <!-- dubbo end -->
今天就先记录到这,下次有时间把maven检测jar冲突的插件集成及使用方式整理一下。

猜你喜欢

转载自blog.csdn.net/codepro_w_/article/details/81318410
今日推荐