您的位置:首页 > 其它

maven的依赖特性,冲突解决(五)

2017-03-09 17:25 295 查看
转载:http://yanan0628.iteye.com/blog/2270409
 

1.maven依赖的几个特性

    1.1 依赖范围 -scope标签
    maven在构建过程有3套classpath,我们会根据配置依赖的范围 依赖不同的classpath,如下图:
    


compile:默认是compile,对 编译 测试 运行 都有效

provided:对编译和测试classpath有效,运行的时候不需要加入,例如 jsp 依赖 searvlet api ,比如我们在编译和测试的时候有效但是在运行的时候  容器已经提供servletapi,如果加入会造成冲突

runtime:只在测试和运行时 有效,比较典型的例子 jdbc api,只有在启动代码测试或者运行的时候才会启用

test:只会在测试时有效,比较典型例子 就是junit ,只有再测试的时候 才会启用

 system (系统范围):system范围依赖与provided 类似,但是你必须显式的提供一个对于本地系统中JAR 文件的路径。这么做是为了允许基于本地

对象编译,而这些对象是系统类库的一部分。这样的构件应该是一直可用的,Maven 也不会在仓库中去寻找它。如果你将一个

依赖范围设置成系统范围,你必须同时提供一个 systemPath 元素。注意该范围是不推荐使用的(你应该一直尽量去从公共或

定制的 Maven 仓库中引用依赖)。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>

    1.2 依赖传递
    比如我们引入某一个依赖spring-test,依赖传递特性会很方便帮助我们记下来它相关的依赖,而不必有时会因为引入jar有问题而烦恼,但是也有弊端,存在一些不必要的依赖,可能会造成冲突。
    


    1.3 依赖排除 -exclusion标签
   
依赖排除的特性 也是为了解决依赖冲突的一个方法,很方便去除依赖传递过程中不必要的依赖。在下面依赖冲突会用到 该标签。
    


用maven管理库依赖,有个好处就是连同库的依赖的全部jar文件一起下载,免去手工添加的麻烦,但同时也带来了同一个jar会被下载了不同版本的问题,好在pom的配置里面允许用<exclusion>来排除一些不需要同时下载的依赖jar 。
      比如配置struts-core,它会同时下载javassist和asm相关的jar,但版本又不够新,这时可以排除它们:

<!-- Struts2 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts.version}</version>
<exclusions>
<exclusion>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
<exclusion> <!-- we prefer our explicit version, though it should be the same -->
<groupId>asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
<exclusion> <!-- we prefer our explicit version, though it should be the same -->
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
</exclusion>
<exclusion> <!-- we prefer our explicit version, though it should be the same -->
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
<exclusion> <!-- we prefer our explicit version, though it should be the same -->
<groupId>org.ow2.asm</groupId>
<artifactId>asm-commons</artifactId>
</exclusion>
</exclusions>
</dependency>


    1.4 依赖冲突产生原因
    使用maven久了会发现存在依赖冲突的问题,由于依赖的传递特性会引入很多隐式的依赖和现有显示jar版本有所冲突,从而造成版本冲突的问题。要解决这个问题,首先就是要查看pom.xml显式和隐式的依赖类包,
然后通过这个类包树找出我们不想要的依赖类包,手工将其排除在外就可以了。
 

2.依赖冲突的解决

     

   2.1两个基本原则:
    1).短路优先原则
        A->B->logback-1.0.jar

        A->logback-1.1.jar
 
     2).先声明先优先原则(先解析先引用)

       与项目A pom中配置 引用坐标的顺序有关,如果依赖B在C前的话 就优先B,反之...
       A->B->logback-1.0.jar

       A->C->logback-1.1.jar
 
    2.2 演示两个原则

    1).创建三个maven工程  
        maven-01,maven-02,maven-03
    2).三个工程依赖结构:   
      maven-01依赖 spring-test,maven-02,maven-03 (maven-02/03需要首先提交本地仓库,maven-01才能找到 ,可以参考寻找构件过程:1.3 仓库寻找构件过程) ;
      maven-02依赖commons-logging-1.1.1;
      maven-03工程依赖 commons-logging-1.1.3
     3).看下myEclipse或者执行mvn dependency:tree 查看依赖树:
 
     myeclispe:依赖树
    


   
  4).冲突解决办法:
 
   4.1  pom配置1:
   

Xml代码  


<dependency>  
    <groupId>org.springframework</groupId>  
    <artifactId>spring-test</artifactId>  
    <version>4.2.2.RELEASE</version>  
    <!-- 依赖排除 可以排除对commons-logging 的依赖  
    <exclusions>  
        <exclusion>  
            <groupId>commons-logging</groupId>  
            <artifactId>commons-logging</artifactId>  
        </exclusion>  
    </exclusions>  
    -->  
</dependency>  
  
<!-- 添加对maven-02依赖 -->  
<dependency>  
    <groupId>com.sohu.train</groupId>  
    <artifactId>maven-02</artifactId>  
    <version>1.0-SNAPSHORT</version>  
</dependency>  

 
 

  短路优先原则:
         maven-01->spring-test->spring-core->commons-loggings-1.2(依赖深度3)
         maven-01->maven-02->commons-loggings-1.1.1(依赖深度2)
         所以maven01工程依赖的commons-loggings-1.1.1
  


 
   4.2 pom配置2:
   

Xml代码  


<dependency>  
    <groupId>org.springframework</groupId>  
    <artifactId>spring-test</artifactId>  
    <version>4.2.2.RELEASE</version>  
    <!-- 依赖排除 -->  
    <exclusions>  
        <exclusion>  
            <groupId>commons-logging</groupId>  
            <artifactId>commons-logging</artifactId>  
        </exclusion>  
    </exclusions>  
</dependency>  
  
<!-- 添加对maven-03依赖  -->  
<dependency>  
    <groupId>com.sohu.train</groupId>  
    <artifactId>maven-03</artifactId>  
    <version>0.0.1-SNAPSHOT</version>  
</dependency>  
  
<!-- 添加对maven-02依赖 -->  
<dependency>  
    <groupId>com.sohu.train</groupId>  
    <artifactId>maven-02</artifactId>  
    <version>1.0-SNAPSHORT</version>  
</dependency>  

 
   先引用先优先的原则:
         maven-01->spring-test->spring-core
         maven-01->maven-02->commons-logging-1.1.1

         maven-01->maven-03->commons-logging-1.1.3

 如果pom先依赖maven-02则 依赖commons-logging-1.1.1 依赖;反之,如果pom先依赖maven-03则 依赖commons-logging-1.1.3 依赖
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: