怎么解决Maven冲突问题

这篇文章主要介绍“怎么解决Maven冲突问题”,在日常操作中,相信很多人在怎么解决Maven冲突问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么解决Maven冲突问题”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

创新互联公司云计算的互联网服务提供商,拥有超过13年的服务器租用、成都移动机房、云服务器、虚拟主机、网站系统开发经验,已先后获得国家工业和信息化部颁发的互联网数据中心业务许可证。专业提供云主机、虚拟主机、空间域名、VPS主机、云服务器、香港云服务器、免备案服务器等。

Maven 回顾

Maven 自述

Maven 是用于构建和管理 Java 项目的工具。对于 Java 方向的来说,Maven 几乎都要接触和使用。当然也有其他的工具来代替  Maven,比如 Ant 和 Gradle。

之前有接触过 Grails 构建的 Java Web 项目,就是用 Gradle 来做依赖管理的。至于 Ant  也在刚工作的时候在一些老项目中有见到过,后面几乎没见过了。

使用 Maven  可以让我们快速构建一个新的项目,并且很方便的可以集成和管理多个三方的框架。当我们需要某个框架时可以去搜索一下这个框架的信息,然后配置到你的项目中即可。

比如我们想要使用 Spring Boot,除了在 Spring 的文档中获取依赖的版本,也可以自己去搜索,选择对应的版本,如下图:

怎么解决Maven冲突问题

可以看到默认就是 Maven 的依赖方式,只需要将 dependency 整段内容复制到项目的 pom.xml  文件中即可。右侧还有很多其他的依赖方式,比如 Gradle 等。

Maven 依赖传递

今天主要讲下如何去解决 Maven 做依赖管理的时候 Jar 包冲突的问题,在解决之前先来了解下基本的知识。

怎么解决Maven冲突问题

上图展示了 Maven 的依赖传递性,首先是项目 B 中依赖了 Spring 和 Guava 两个框架。然后项目 A 又依赖了项目 B,所以项目 A  也会依赖 Spring 和 Guava 两个框架。

依赖传递 Jar 包选择逻辑依赖性传递会导致项目中依赖很多其他版本的 Jar,这种情况下怎么进行 Jar 包的选择呢?

有两个规则:

  • 不同距离,距离近优先

  • 相同距离,前者优先

如下图所示,项目依赖了项目 A 和项目 B,A 和 B 分别依赖了 Guava,但是从依赖层次来看,项目 B 的层次更浅,故 Guava18.0  会被优先选择。

怎么解决Maven冲突问题

当距离相同的时候,就会优先选择定义在前面的,如下图所示,项目 A 和项目 B 都分别依赖了 Guava15.0 和 Guava18.0 的版本,但是项目  A 的顺序在项目 B 的前面,所以会优先选择 Guava15.0 版本。

怎么解决Maven冲突问题

通过依赖传递性经常会导致 Jar 包冲突的问题,比如下图的项目 A 本身依赖了 Guava15.0,然后又依赖了项目 B,项目 B 中依赖了  Guava18.0,这样项目 A 就会同时依赖 Guava15.0 和 Guava18.0。

如果刚好用到了高版本不兼容低版本的方法和类时,就会出现选择错误,因为 Maven 会根据依赖树的深浅来选型浅的依赖,也就是 15.0。

怎么解决Maven冲突问题

冲突案例

下面就是一个典型的 Jar 包冲突问题,当一个 Jar 有多个版本的时候,就会出现冲突。

错误信息可以看到 com.google.common.collect.FluentIterable.concat 这个方法找不到,目前是从  guava-18.0.jar 中加载的,这种问题我们该怎么解决呢?

Description: An attempt was made to call the method com.google.common.collect.FluentIterable.concat(Ljava/lang/Iterable;Ljava/lang/Iterable;)Lcom/google/common/collect/FluentIterable; but it does not exist. Its class, com.google.common.collect.FluentIterable, is available from the following locations:     jar:file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar!/com/google/common/collect/FluentIterable.class It was loaded from the following location:     file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar  Action: Correct the classpath of your application so that it contains a single, compatible version of com.google.common.collect.FluentIterable

解决思路之悬丝诊脉

找出冲突的 Jar,看看当前项目中依赖了哪几个版本。

Eclipse

在 Eclipse 中可以双击 pom 文件,进入 Dependency 视图,输入你要搜索的 jar  名称进行搜索,就可以看出当前项目中哪些框架依赖了你搜索的 jar,什么版本都能知道。

怎么解决Maven冲突问题

Idea

Idea 中可以安装 maven helper 插件来查看相关依赖信息,默认选中 Conflicts  会展示当前项目存在冲突的依赖,当然我们也可以直接查看树形的依赖关系去分析冲突。

怎么解决Maven冲突问题

Maven 命令

不用不借助于开发工具的插件,我们可以直接用 Maven  命令来查看当前项目的依赖关系,命令行进入到你要分析的项目目录下,执行下面的命令将分析结果保存到文件中:

mvn dependency:tree > tree.log

执行完之后依赖的信息结构如下:

怎么解决Maven冲突问题

搜索了下 guava,发现在 smjdbctemplate 中依赖了 18.0 版本,这个框架是我自己基于 jdbctemplate  封装的一个框架。

怎么解决Maven冲突问题

解决思路之察言观色其实很明显,错误信息已经告诉我们 18.0 中找不到 concat 方法,所以 18.0 肯定是不能用的,通过前面的分析,找到了直接依赖  guava.18.0.jar 的是 smjdbctemplate,解决办法就是将 smjdbctemplate 中的 guava 排除掉。

   com.github.yinjihuan   smjdbctemplate   1.1               com.google.guava       guava         

还有就是根据依赖树的深浅度来判断当前项目依赖的是哪个版本,如下图:

怎么解决Maven冲突问题

18.0 是最浅的,肯定是依赖它,其实在 Eclipse 里面直接查看 Maven Dependencies  就可以指定当前项目依赖哪些框架和版本信息,如下图:

怎么解决Maven冲突问题

当我们排除掉 18.0 后再来看依赖的版本是 20.0,如下图:

怎么解决Maven冲突问题

根据依赖树的深浅度,20.0 和 19.0 都是一样的层级,但是 20.0 在 19.0 前面,所以优先选择 20.0 版本。

再来看项目中的 pom 文件,发现 swagger 的声明顺序在 apollo 的前面。

怎么解决Maven冲突问题

如果我们把顺序调整一下,那么就会依赖 19.0 的版本。

怎么解决Maven冲突问题

到此,关于“怎么解决Maven冲突问题”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!


网站栏目:怎么解决Maven冲突问题
文章地址:http://scyanting.com/article/pcsjco.html