maven依赖冲突解决

  • 解决方案
  • maven版本以来的缘由
  • Maven 的依赖仲裁原则
  • IDEA实践
  • 拓展(maven元素含义及注意事项)


解决方案

解决方案: 以idea 操作为例, 打开maven依赖的图,确定要使用的jar的版本,将冲突的jar包给exclude。

maven版本以来的缘由

. 软件工程是多人合作的结果,我们在开发软件的时候经常会使用一些别人编写好的,比较成熟的库。 比如,早期的前端开发用到了 jQuery库,那么通常的做法是去官网下载一个最新版本的
jQuery,然后放在自己本地的项目中。对于简单的前端项目来说,这样可以简单粗暴地达到目的。但当项目越来越庞大,除了 jQuery
之外,你还会依赖一些其他的第三方库。比如 Bootstrap 与 Chosen,这两个流行的前端库也都依赖jQuery,如果这些第三方库依赖的 jQuery 版本一致还好,但大多数情况并没有这么乐观:

你的项目依赖的 jQuery 版本是1.0.0 ,Bootstrap 依赖的版本是 1.1.0,而 Chosen 依赖的版本是 1.2.0,
看上去都是小版本不一致,一开始并没有发现任何问题,但是如果到后期发现不兼容,可能就为时已晚了。

所以,你需要在确定依赖之前,就把整个系统的依赖全部梳理一遍,保证每个依赖都不会有冲突问题。

Maven 的依赖仲裁原则

Maven 的依赖仲裁原则如下:

第一原则: 最短路径优先原则。 比如,A 依赖了 B 和 C,而 B 也依赖了 C,那么 Maven 会使用 A 依赖的 C 的版本,因为它的路径是最短的。

maven常见的依赖冲突 maven依赖冲突解决_maven依赖

第二原则: 第一声明优先原则。比如,A 依赖了 B 和 C,B 和 C 分别依赖了 D,那么 Maven 会使用 B 依赖的 D 的版本,因为它是最先声明的。根据这两个原则,Maven 就可以确定一个项目所有依赖的列表,但它处理依赖的方式还是有些简单粗暴。有时 Maven 的决定结果并不是你想要的,所以我们在使用 Maven 的时候还是要多加小心。

maven常见的依赖冲突 maven依赖冲突解决_maven依赖_02

IDEA实践

IDEA实践:

打开依赖:

maven常见的依赖冲突 maven依赖冲突解决_maven常见的依赖冲突_03


1.选择Maven Project

2.选中Dependencies

3.点击 Show Dependencies

效果如下图所示

maven常见的依赖冲突 maven依赖冲突解决_idea版本依赖_04


如果依赖的jar包很多,不好找那么我们可以用Ctrl+F快捷键进行搜索

maven常见的依赖冲突 maven依赖冲突解决_idea版本依赖_05


如果我们仔细观察上图,会发现在项目依赖图中,有一些红色标记的线,实际上,这些红色标记出来的线所指向的 jar 包,就是项目中冲突的 jar 包!且在我们点击 jar 包之后,还会显示出多条指向 jar 包的红色虚线,其代表着该 jar 包被多次引用,及具体引用路径。

如上图所示,想要排除冲突的 jar 包,其方法为:点击冲突的 jar 包,右键呼出菜单栏,点击Exclude选项。

maven常见的依赖冲突 maven依赖冲突解决_maven常见的依赖冲突_06


如下图所示,在排除冲突的 jar 包之后,pom.xml文件会自动更新,添加排除语句。

maven常见的依赖冲突 maven依赖冲突解决_maven版本依赖_07

拓展(maven元素含义及注意事项)

在 POM 中,根元素 project 下的 dependencies 可以包含一个或多个 dependency 元素,以声明一个或者多个项目依赖。每个依赖可以包含的元素有:

groupId、artifactId、version: 依赖的基本坐标;
			type: 依赖的类型,默认为 jar;
			scope: 依赖的范围;
			optional: 标记依赖是否可选;
			exclusions: 用来排除传递性依赖

要想用好 Maven 管理依赖,你必须理解每一项的含义,而新手通常傻傻分不清楚。举个例子,依赖范围这一项,Maven 在不同的时期会使用不同的 classpath :

  • 比如,junit 只有在测试的时候有用,那么将其设为 test scope 就可以;
  • 再比如 ,servlet API 这个 jar 包只需要在编译的时候提供接口,但是实际在运行时会有对应的 servlet 容器提供,所以没必要打到 war 包中去,这时候只需要指定在 provided scope 就可以了。通过指定 provided
    scope 的方式可以让每个依赖各司其职,不用弄成“一锅粥”。
  • 包管理工具还解决了依赖传递的问题,比如你的项目 A 依赖了 B,而 B 依赖了 C 和 D,那么在获取依赖的时候会把 B、C、D 都一起拉下来,这样可以节省大量的时间。