【maven】maven查看项⽬依赖并解决依赖冲突的问题
参考:
参考:
参考:
参考:
参考:(查看依赖冲突解决办法)
maven学习笔记系列:
⼀、问题
项⽬开发过程中,经常会遇到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依赖树?
//进⼊项⽬的l⽂件的⽬录下,运⾏如下命令
//这个是正常依赖的树
mvn dependency:tree
//这个命令是查看maven是如何解决依赖冲突的依赖树
mvn -Dverbose dependency:tree
//如果想将依赖树打印到指定⽂件中,则命令如下
mvn -Dverbose dependency:tree -Doutput=/Users/
View Code
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&le.guava</groupId>
</exclusion>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
View Code
====================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&stng</groupId>
<artifactId>testng</artifactId>
<version>5.7</version>
<classifier>jdk15</classifier>
</dependency>
View Code
2、maven依赖范围
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
View Code
上⾯的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>
View Code
在⼦pom中添加依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
View Code
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>
View Code
5、依赖版本界限
要求的依赖版本>=3.8且<4.0
<version>[3.8,4.0)</version>
View Code
要求的依赖版本<=3.8.1
<version>[,3.8.1]</version>
View Code
要求必须是3.8.1版本,如果不是的话会构建失败,提⽰版本冲突。原来的写法<version>3.8.1</version>的意思是所有版本都可以,但最好是3.8.1
<version>[3.8.1]</version>
View Code
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>
View Code
替换依赖
直接使⽤上⼀步中的排除掉,然后添加要替换进来的依赖就可以了,没有什么特殊的标志来标志这个是替换进来的。
7、版本冲突仲裁
版本仲裁规则(在maven 2.2.1版本上测试验证)
• 按照项⽬总POM的DependencyManager版本声明进⾏仲裁(覆盖),但⽆警告。
• 如⽆仲裁声明,则按照依赖最短路径确定版本。
• 若相同路径,有严格区间限定的版本优先。
• 若相同路径,⽆版本区间,则按照先⼊为主原则。
View Code
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引⼊的,那么在l中到这个依赖,做其它的调整:
<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 SUCCESSmysql下载jar包
============将依赖的jar包打到依赖服务内的命令========
mvn clean -U package -pl [moudel-name] -am -P prod -Dmaven.source.skip=true -st.skip=true
View Code
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论