女朋友他们项目用了 spring-boot,以 spring-boot-parent 作为 parent:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.9</version>
</parent>

女朋友最近想用 elasticsearch 作为搜索引擎,在项目中添加了依赖

<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.10.2</version>
</dependency>

写好代码,一跑,报类不存在异常:

 java.lang.NoClassDefFoundError: org/elasticsearch/common/xcontent/DeprecationHandler
at com.lv.springboot.datasource.ClientUTis.main(ClientUTis.java:13)
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.common.xcontent.DeprecationHandler
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

女朋友看了依赖mvn dependency:tree,发现依赖的elasticsearch版本是:

org.elasticsearch.client:elasticsearch-rest-high-level-client:7.0.1
|--org.elasticsearch:elasticsearch:5.6.16
|--org.elasticsearch.client:elasticsearch-rest-client:7.0.1
|--org.elasticsearch.plugin:parent-join-client:7.0.1
|--org.elasticsearch.plugin:aggs-matrix-stats-client:7.0.1
|--org.elasticsearch.plugin:rank-eval-client:7.0.1
|--org.elasticsearch.plugin:lang-mustache-client:7.0.1

女朋友很着急,明明指定了elasticsearch的依赖了啊,而且是项目的根 pom,依赖不是最短路径原则么?不应该以这个依赖为准么?

女朋友于是找我求助,本着面向“对象”,我立马放下手头工作帮忙查看。仔细一看,原来SpringBoot的DependencyManagement中,org.elasticsearch:elasticsearch已经被包含了(以下为节选):

<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.9.RELEASE</version> <properties>
<elasticsearch.version>5.6.16</elasticsearch.version>
</properties> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

spring-boot 其实已经考虑到用户可能要换版本了,所以将版本放入了 <properties/>,properties 也具有最短路径原则,所以可以通过在你的项目根 pom 中的 properties 增加相同 key 修改版本:

<properties>
<elasticsearch.version>7.10.2</elasticsearch.version>
</properties>

所有可以这么替换的属性, spring-boot 官方文档已经列出了,参考官方文档附录:Version Properties

也可以通过 dependencyManagement 的最短路径原则,通过在你的项目根 pom 中的增加想修改依赖的 dependencyManagement 即可:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.10.2</version>
</dependency>
</dependencies>
</dependencyManagement>

最后,可以记住下面的原则,就知道项目的依赖到底是哪个版本啦:

Maven依赖可以分为如下几部分:

  1. 直接依赖,就是本项目 dependencies 部分的依赖
  2. 间接依赖,就是本项目 dependencies 部分的依赖所包含的依赖
  3. 依赖管理,就是本项目 dependency management 里面的依赖
  4. parent 的直接依赖
  5. parent 的间接依赖
  6. parent 的依赖管理
  7. bom 的直接依赖(一般没有)
  8. bom 的间接依赖(一般没有)
  9. bom 的依赖管理

可以这么理解依赖:

  1. 首先,将 parent 的直接依赖,间接依赖,还有依赖管理,插入本项目,放入本项目的直接依赖,间接依赖还有依赖管理之前
  2. 对于直接依赖,如果有 version,那么就依次放入 DependencyMap 中。如果没有 version,则从依赖管理中查出来 version,之后放入 DependencyMap 中。key 为依赖的 groupId + artifactId,value为version,后放入的会把之前放入的相同 key 的 value 替换
  3. 对于每个依赖,各自按照 1,2 加载自己的 pom 文件,但是如果第一步中的本项目 dependency management 中有依赖的版本,使用本项目 dependency management的依赖版本,生成 TransitiveDependencyMap,这里面就包含了所有的间接依赖。
  4. 所有间接依赖的 TransitiveDependencyMap, 对于项目的 DependencyMap 里面没有的 key,依次放入项目的 DependencyMap
  5. 如果 TransitiveDependencyMap 里面还有间接依赖,那么递归执行3, 4。

由于是先放入本项目的 DependencyMap,再去递归 TransitiveDependencyMap,这就解释了 maven 依赖的最短路径原则。

Bom 的效果基本和 Parent 一样,只是一般限制中,Bom 只有 dependencyManagement 没有 dependencies

解决了问题并且给妹子梳理明白之后,妹子答应这个月多给我 100 块零用钱啦,开心~~~~~

每日一刷,轻松提升技术,斩获各种offer:

急~为啥我指定的的maven依赖版本没有生效?不是最短路径原则吗?的更多相关文章

  1. Maven依赖版本冲突的分析及解决小结

    1:前言 做软件开发这几年遇到了许多的问题,也总结了一些问题的解决之道,之后慢慢的再遇到的都是一些重复性的问题了,当然,还有一些自己没有完全弄明白的问题.如果做的事情是重复的,遇到重复性问题的概率也就 ...

  2. java——maven依赖版本冲突

    博客:maven依赖jar包时版本冲突的解决

  3. CDH5.16.1的maven依赖版本查询地址

    1查询官网地址,提供了详细的各个版本的jar依赖版本信息 https://www.cloudera.com/documentation/enterprise/release-notes/topics/ ...

  4. 转:MAVEN依赖的是本地工程还是仓库JAR包?

    相信大家都碰见过 maven 配置的依赖或者是 jar 包或者是工程,在开发的过程当中,我们当然需要引入的是工程,这样查看 maven 依赖的文件的时候,就能直接查看到源码. 一.本地工程依赖 举个例 ...

  5. Maven依赖的是本地工程还是仓库jar包?

    相信大家都碰见过maven配置的依赖或者是jar包或者是工程,在开发的过程当中,我们当然需要引入的是工程,这样查看maven依赖的文件的时候,就能直接查看到源码. 一.本地工程依赖 举个例子,其架构如 ...

  6. Maven传递依赖的坑:父pom中dependencyManagement版本优先级高于传递依赖版本

    一.由来 之前同事问了个问题,就是当前工程为spring boot项目,假设版本号为2.0.3 这个项目中依赖了一个spring boot项目依赖(先别管为啥有这么奇葩的依赖,这个版本是1.5.9). ...

  7. (十)Maven依赖详解

    1.何为依赖? 比如你是个男的,你要生孩子,呸呸呸...男的怎么生孩子,所以你得依赖你老婆,不过也不一定咯,你也可以依赖其她妹子. 我们在平时的项目开发中也是同理,你需要依赖一些东西才能实现相应的功能 ...

  8. Maven依赖(转)

    相同依赖级别,先加入的先依赖不同依赖级别,级别短的先依赖 version-->SNAPSHOTxxx-里程碑-->SNAPSHOT,alpha,beta,Release(RC),GA()s ...

  9. Maven依赖解析

    本文将记录Maven工程中依赖解析机制,内容包括: Maven依赖基本结构 从仓库解析依赖的机制 依赖传递性解析实例 1. Maven依赖基本结构 上篇文章记录了Maven依赖的聚合与继承,POM中依 ...

随机推荐

  1. [LeetCode]160. Intersection of Two Linked Lists判断交叉链表的交点

    方法要记住,和判断是不是交叉链表不一样 方法是将两条链表的路径合并,两个指针分别从a和b走不同路线会在交点处相遇 public ListNode getIntersectionNode(ListNod ...

  2. Redis集群搭建采坑总结

    背景 先澄清一下,整个过程问题都不是我解决的,我在里面就是起了个打酱油的角色.因为实际上我负责这个项目,整个过程也比较清楚.之前也跟具体负责的同事说过,等过段时间带他做做项目复盘.结果一直忙,之前做的 ...

  3. 循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理

    在很多列表展示数据的场合中,大多数都会需要一个排序的处理,以方便快速查找排序所需的数据,本篇随笔介绍如何结合ABP后端和Vue+Element前端结合的分页排序处理过程. 1.Vue+Element前 ...

  4. .NET 云原生架构师训练营(模块二 基础巩固 EF Core 更新和迁移)--学习笔记

    2.4.6 EF Core -- 更新 状态 自动变更检测 不查询删除和更新 并发 状态 Entity State Property State Entity State Added 添加 Uncha ...

  5. js实现页面消息滚动效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 强化学习 1 --- 马尔科夫决策过程详解(MDP)

    强化学习 --- 马尔科夫决策过程(MDP) 1.强化学习介绍 ​ 强化学习任务通常使用马尔可夫决策过程(Markov Decision Process,简称MDP)来描述,具体而言:机器处在一个环境 ...

  7. css浅谈

    一 CSS文字属性: color : #999999; /*文字颜色*/ font-family : 宋体,sans-serif; /*文字字体*/ font-size : 9pt; /*文字大小*/ ...

  8. item系列魔法方法

    class Foo: def __init__(self, name): self.name = name def __getitem__(self, item): print('getitem执行' ...

  9. centos7.5安装Oracle11gR2

    centos7.5安装Oracle11gR2 说明:由于上一台旧的笔记本电脑(CPU:i5-7200,内存:8G,硬盘:128SSD+1T机械)卸任,所以打算在家搭建一个个人服务器(主要是换不锈钢盆不 ...

  10. Akka Typed 官方文档之随手记

    ️ 引言 近两年,一直在折腾用FP与OO共存的编程语言Scala,采取以函数式编程为主的方式,结合TDD和BDD的手段,采用Domain Driven Design的方法学,去构造DDDD应用(Dom ...