Maven——依赖冲突(九)

前言

当我们使用 Maven 来构建我们的程序时,我们可以用几句配置来代替大量的 Jar 包,同时因为这种配置在我们交流代码时可以不用自己引入 Jar 包(避免了版本不一致而出错),只要更新 Maven,它就会在后台帮我们解决这一切。但是在我们享受这种方便的同时,我们也在为这种方便付出代价。通常都是版本不一致出现的依赖冲突。

依赖冲突-例

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>

其依赖树如下:

Maven——依赖冲突(九)_2020-07-17-11-04-10.png

我们可以清楚地看到 hibernate-core 所依赖的 jboss-logging 被省略了 (灰色的那一个依赖),因为 Maven ( 或者说是 Java 的 ClassLoader ) 先加载了 hibernate-validator 所依赖的 jboss-logging,就会忽略其他同名依赖。 一般情况来说, 这是不会出现问题的, 因为在你使用 Maven 时, 你已经不知不觉地通过这种方式多次使你的代码正确执行了, 但是一旦出现了错误, 你多半会被坑的死去活来 ~. ~

比如我举的这个例子, 当你初始化 SessionFactory 时, 你将会见到如下错误提醒:

java.lang.NoSuchMethodError: org.hibernate.internal.CoreMessageLogger.debugf(Ljava/lang/String;II)V

首先检查类或方法是否存在,如果找到类,却没有在该类及其父类中找到该方法,那么百分百就是版本错误。

最终确定是 jboss-logging 版本错误。

冲突解决

  1. 将重要的依赖放在前面

因为 maven 会优先加载第一个遇到的版本,所以我们只需要将 hibernate-core 移到 hibernate-validator 的前面,这样 Maven 就会加载到 3.3.0 这个版本。

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
  1. 使用 exclusions 标记排除依赖

将干扰的依赖排除后就没有后顾之忧了,如下:

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
  1. 使用 mvn dependency:tree 命令查看依赖树

mvn dependency:tree 选项

  • verbose 显示全部,不使用此选项则显示部分。当然了,这不是让你一次性显示所有依赖出来,因为太多了,显示出来的话阅读难度指数上升,有兴趣可亲身一试 ~. ~

  • includes 筛选出想要的的依赖,使用时只显示被加载的 jar 包,如果和 verbose 一起使用则可以查看被忽略的 jar 包,如下

  • excludes 这个就没什么好说的,includes 相反的作用

    mvn dependency:tree -Dverbose -Dincludes=org.jboss.logging:jboss-logging
文章目录
  1. 1. 前言
  2. 2. 依赖冲突-例
  3. 3. 冲突解决
|