参考:https://timup.iteye.com/blog/1725898

参考:http://ian.wang/106.htm

参考:https://www.jianshu.com/p/7b4d3453bb14?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

参考:https://blog.csdn.net/u014515854/article/details/80407024

参考:http://www.mamicode.com/info-detail-2246820.html  (查看依赖冲突解决办法)

maven学习笔记系列:https://blog.csdn.net/u011781521/article/details/79055605

一、问题

项目开发过程中,经常会遇到jar冲突,然后maven根据自己的规则进行冲突解决,导致项目在运行的过程中报错。

1、maven自动解决依赖冲突的规则是什么?

2、如何查看当前项目的maven的依赖树?

3、如何从依赖树中找到自己预期的版本,是被那个jar给覆盖了?

4、如何人工进行依赖冲突解决,达到使用目的?

二、解决问题

1、maven自动解决依赖冲突的规则是什么?

第一原则:路径最近者优先

项目A有如下的依赖关系:

A->B->C->X(1.0)

A->D->X(2.0)

则该例子中,X的版本是2.0

第二原则:路径相等,先声明者优先

项目A有如下的依赖关系:

A->B->Y(1.0)

A->C->Y(2.0)

若pom文件中B的依赖坐标先于C进行声明,则最终Y的版本为1.0

2、如何查看当前项目的maven依赖树?

//进入项目的pom.xml文件的目录下,运行如下命令
//这个是正常依赖的树
mvn dependency:tree
//这个命令是查看maven是如何解决依赖冲突的依赖树
mvn -Dverbose dependency:tree
//如果想将依赖树打印到指定文件中,则命令如下
mvn -Dverbose dependency:tree -Doutput=/Users/shangxiaofei/sxfoutput.txt

3、如何从依赖树中找到自己预期的版本,是被那个jar给覆盖了?

例子:

递归依赖的关系列的算是比较清楚了,每行都是一个jar包,根据缩进可以看到依赖的关系。
最后写着compile的就是编译成功的。
最后写着omitted for duplicate的就是有jar包被重复依赖了,但是jar包的版本是一样的。
最后写着omitted for conflict with xxxx的,说明和别的jar包版本冲突了,而该行的jar包不会被引入。比如上面有一行最后写着omitted for conflict with 3.4.6,那么该行的zookeeper:jar:3.4.8不会被引入,会引入3.4.6版本

最后写着version managed from 2.3 ;omitted for duplicate ,表示最终使用commons-pool2最终会使用2.4.2,拒绝使用<dependencyManagement></dependencyManagement>中声明的2.3版本

最后写着version managed from 1.16.8 ;表示最终使用lombok:jar:1.16.22版本

4、如何人工进行依赖冲突解决,达到使用目的?

解决重复依赖和冲突的方法:

1,修改pom文件中两个dependency元素的位置。如果两个dependency都引用了一个jar包,但是版本不同,classloader只会加载jar包在pom文件中出现的第一个版本,以后出现的其他版本的jar包会被忽略。

不建议使用该方法,因为引用不同版本的jar包本身就是很危险的。

2,使用<exclusions>标签来去掉某个dependency依赖中的某一个jar包或一堆jar包,<exclusion>中的jar包或者依赖的相关jar包都会被忽略,从而在两个dependency都依赖某个jar包时,可以保证只使用其中的一个。

可以这么写:

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.3.2</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>

====================Maven坐标基础知识===================

1、maven的依赖基础

<dependency>
<groupId>com.alibaba.share</groupId>
<artifactId>test</artifactId>
<version>1.4</version>
</dependency> 依赖库命名规则:
${groupId.part1}/${groupId.part2}/${version}
例:com/alibaba/share/1.4 依赖库文件命名规则:
${artifactId}-${version}-${classifier}.${type}
例:test-1.4-source.jar 注:classfier即分类器,多数的时候是用不到的,不过有写情况需要,例:
TestNG强制需要你提供分类器,以区别jdk14和jdk15
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.7</version>
<classifier>jdk15</classifier>
</dependency>

2、maven依赖范围

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

上面的scope即约定依赖范围。 
compile:默认值,一直可用,最后会被打包 
provided:编译期间可用,不会被传递依赖,不会被打包。例:依赖于web容器中的提供的一个jar包,在编译的时候需要加入依赖(web容器还没有介入),运行的时候由web容器来提供。 
test:执行单元测试时可用,不会被打包,不会被传递依赖 
runtime:运行和测试时需要,但编译时不需要 
system:不推荐使用

3、maven依赖管理

避免不同子模块中依赖版本冲突 
在父pom中配置依赖

<dependencyManagement>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.2</version>
</dependency>
...
<dependencies>
</dependencyManagement>

在子pom中添加依赖

<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>

dependencyManagement实际上不会真正引入任何依赖,在子pom中添加之后才会。在父pom中配置了之后,子模块只需使用简单groupId和artifactId就能自动继承相应的父模块依赖配置。如果子pom中定义了version,则覆盖management中的。

4、可选依赖

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>1.5</version>
<optional>true</optional>
</dependency>

5、依赖版本界限

要求的依赖版本>=3.8且<4.0

<version>[3.8,4.0)</version>   

要求的依赖版本<=3.8.1

<version>[,3.8.1]</version>    

要求必须是3.8.1版本,如果不是的话会构建失败,提示版本冲突。原来的写法<version>3.8.1</version>的意思是所有版本都可以,但最好是3.8.1

<version>[3.8.1]</version>   

6、排除依赖

依赖project-a但是排除掉对project-a中引入的project-b的依赖 

<dependency>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>project-a</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>project-b</artifactId>
</exclusion>
</exclusions>
</dependency>

替换依赖 
直接使用上一步中的排除掉,然后添加要替换进来的依赖就可以了,没有什么特殊的标志来标志这个是替换进来的。

7、版本冲突仲裁

版本仲裁规则(在maven 2.2.1版本上测试验证)
• 按照项目总POM的DependencyManager版本声明进行仲裁(覆盖),但无警告。
• 如无仲裁声明,则按照依赖最短路径确定版本。
• 若相同路径,有严格区间限定的版本优先。
• 若相同路径,无版本区间,则按照先入为主原则。

8、依赖冲突解决办法

查看那些jar包依赖了冲突包的命令

mvn dependency:tree -Dverbose -Dincludes=被依赖的包

刚才吹嘘dependency:tree时,我用到了“无处遁形”,其实有时你会发现简单地用dependency:tree往往并不能查看到所有的传递依赖。不过如果你真的想要看所有的,必须得加一个-Dverbose参数,这时就必定是最全的了。
全是全了,但显示出来的东西太多,头晕目眩,有没有好法呢?当然有了,加上Dincludes或者Dexcludes说出你喜欢或讨厌,dependency:tree就会帮你过滤出来:
引用
Dincludes=org.springframework:spring-tx
过滤串使用groupId:artifactId:version的方式进行过滤,可以不写全啦,如:

mvn dependency:tree -Dverbose -Dincludes=asm:asm

就会出来asm依赖包的分析信息:

[INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ ridge-test ---
[INFO] com.ridge:ridge-test:jar:1.0.2-SNAPSHOT
[INFO] +- asm:asm:jar:3.2:compile
[INFO] \- org.unitils:unitils-dbmaintainer:jar:3.3:compile
[INFO]    \- org.hibernate:hibernate:jar:3.2.5.ga:compile
[INFO]       +- cglib:cglib:jar:2.1_3:compile
[INFO]       |  \- (asm:asm:jar:1.5.3:compile - omitted for conflict with 3.2)
[INFO]       \- (asm:asm:jar:1.5.3:compile - omitted for conflict with 3.2)
[INFO] ------------------------------------------------------------------------

对asm有依赖有一个直接的依赖(asm:asm:jar:3.2)还有一个传递进入的依赖(asm:asm:jar:1.5.3)

第二板斧:将不想要的传递依赖剪除掉

承上,假设我们不希望asm:asm:jar:1.5.3出现,根据分析,我们知道它是经由org.unitils:unitils-dbmaintainer:jar:3.3引入的,那么在pom.xml中找到这个依赖,做其它的调整:

<dependency>  
        <groupId>org.unitils</groupId>  
        <artifactId>unitils-dbmaintainer</artifactId>  
        <version>${unitils.version}</version>  
        <exclusions>  
            <exclusion>  
                <artifactId>dbunit</artifactId>  
                <groupId>org.dbunit</groupId>  
            </exclusion>  
            <!-- 这个就是我们要加的片断 -->  
            <exclusion>  
                <artifactId>asm</artifactId>  
                <groupId>asm</groupId>  
            </exclusion>  
        </exclusions>  
    </dependency>

再分析一下,你可以看到传递依赖没有了:

[INFO]  
    [INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ ridge-test ---  
    [INFO] com.ridge:ridge-test:jar:1.0.2-SNAPSHOT  
    [INFO] \- asm:asm:jar:3.2:compile  
    [INFO] ------------------------------------------------------------------------  
    [INFO] BUILD SUCCESS

【maven】maven查看项目依赖并解决依赖冲突的问题的更多相关文章

  1. SpringBoot+Maven多模块项目(创建、依赖、打包可执行jar包部署测试)完整流程

    一,创建Maven多模块项目先建立外层父工程         File →new →project  选择Spring Initializr          Next下一步到以下页面 工程结构如下 ...

  2. maven 使用 国内镜像的方法 解决依赖下载慢

    转自:http://blog.csdn.net/banqgg/article/details/55804569 Maven是当前流行的项目管理工具,但官方的库在国外经常连不上,连上也下载速度很慢.国内 ...

  3. Maven多模块项目新建技巧-解决公共项目install之后可以在单独模块中直接编译

    说明:如果按照这种方式http://www.cnblogs.com/EasonJim/p/8303878.html,且按照常规的install方式在子项目中编译项目,那么需要先install一下par ...

  4. maven第一次创建项目太慢解决方法

    问题: 第一次用maven创建项目的时候,因为本地仓库中没有jar包,需要从中央仓库下载,所以会比较慢 解决方法: 因为从中央仓库下载默认使用的国外的镜像下载,速度比较慢,我们可以把镜像修改为从阿里云 ...

  5. IDEA maven项目中引入ojdbc依赖报红色波浪线问题的解决办法

    1.pom.xml配置文件中删除ojdbc的依赖配置后更新maven项目,然后再到本地仓库中将ojdbc这个文件夹删除 2.在网上下载ojdbc14.jar,然后改名为ojdbc14-10.2.0.2 ...

  6. 解决Maven项目中jar包依赖冲突问题

    版本冲突的解决方案 [1]调节原则 [1]路径最短者优先原则 [2]路径相同时,先声明者优先原则 [2]排除原则:用于排除某项依赖的依赖jar包 <dependency> <grou ...

  7. maven中import scope依赖方式解决单继承问题的理解

    在maven多模块项目中,为了保持模块间依赖的统一,常规做法是在parent model中,使用dependencyManagement预定义所有模块需要用到的dependency(依赖) <d ...

  8. 利用mvn/maven如何检查依赖冲突,并解决依赖冲突

    mvn/maven如何检查依赖冲突,并解决依赖冲突 如图,点击图示位置,就可以把整个项目的依赖关系展示出来 在图里选中一个artifact,则所有依赖该artifact的地方都会一起连带出来突出显示, ...

  9. Maven 基础(二) | 解决依赖冲突的正确姿势

    一.依赖原则 假设,在 JavaMavenService2 模块中,log4j 的版本是 1.2.7,在 JavaMavenService1 模块中,它虽然继承于 JavaMavenService2 ...

随机推荐

  1. Mysql找回丢失密码

    (先进入root权限):# /etc/init.d/mysql stop# mysqld_safe --user=mysql --skip-grant-tables --skip-networking ...

  2. html回顾随笔JS(*^__^*)

    ---恢复内容开始--- map遍历 function b(){ var week = new Map(); week.set("Mon","星期一"); we ...

  3. L1-056 猜数字

    一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢.本题就要求你找出其中的赢家. 输入格式: 输入在第一行给出一个正整数N(≤10​4​​).随后 N 行,每行给出一个玩 ...

  4. Ubuntu 修改 /etc/resolv.conf 被清空 或重启不生效解决

    sudo gedit /etc/NetworkManager/NetworkManager.conf 注释掉 dns=dnsmasq [main] plugins=ifupdown,keyfile,o ...

  5. SharePoint online Multilingual support - Development(2)

    博客地址:http://blog.csdn.net/FoxDave 上一节讲了如何通过Code的方式设置Site和List级别的国际化,本节介绍一下如何设置Content type和Site co ...

  6. Python 基础day4

    整体大纲关于占位符 tpl = "i am %s" % "alex"   tpl = "i am %s age %d" % ("a ...

  7. C# 创建 写入 读取 excel

    public static void CreateExcelFile(string FileName, List<UUser> luu) { ] == "xlsx")/ ...

  8. robotframework·WEB项目

    date:2018527 day11 一.项目分层 1.测试数据(配置变量,如网址.用户名.密码等) 2.关键字(关键字封装,要调用直接使用关键字名即可,输入内容.点击元素.滚动滑动条等等) 3.测试 ...

  9. HDU 6095 17多校5 Rikka with Competition(思维简单题)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  10. python2.6.6 升级 2.7.X

    下载包 解压 cd 进入 ./configure && make all && make install && make clean && ...