急~为啥我指定的的maven依赖版本没有生效?不是最短路径原则吗?
女朋友他们项目用了 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依赖可以分为如下几部分:
- 直接依赖,就是本项目 dependencies 部分的依赖
- 间接依赖,就是本项目 dependencies 部分的依赖所包含的依赖
- 依赖管理,就是本项目 dependency management 里面的依赖
- parent 的直接依赖
- parent 的间接依赖
- parent 的依赖管理
- bom 的直接依赖(一般没有)
- bom 的间接依赖(一般没有)
- bom 的依赖管理
可以这么理解依赖:
- 首先,将 parent 的直接依赖,间接依赖,还有依赖管理,插入本项目,放入本项目的直接依赖,间接依赖还有依赖管理之前
- 对于直接依赖,如果有 version,那么就依次放入 DependencyMap 中。如果没有 version,则从依赖管理中查出来 version,之后放入 DependencyMap 中。key 为依赖的 groupId + artifactId,value为version,后放入的会把之前放入的相同 key 的 value 替换
- 对于每个依赖,各自按照 1,2 加载自己的 pom 文件,但是如果第一步中的本项目 dependency management 中有依赖的版本,使用本项目 dependency management的依赖版本,生成 TransitiveDependencyMap,这里面就包含了所有的间接依赖。
- 所有间接依赖的 TransitiveDependencyMap, 对于项目的 DependencyMap 里面没有的 key,依次放入项目的 DependencyMap
- 如果 TransitiveDependencyMap 里面还有间接依赖,那么递归执行3, 4。
由于是先放入本项目的 DependencyMap,再去递归 TransitiveDependencyMap,这就解释了 maven 依赖的最短路径原则。
Bom 的效果基本和 Parent 一样,只是一般限制中,Bom 只有 dependencyManagement 没有 dependencies
解决了问题并且给妹子梳理明白之后,妹子答应这个月多给我 100 块零用钱啦,开心~~~~~
每日一刷,轻松提升技术,斩获各种offer:

急~为啥我指定的的maven依赖版本没有生效?不是最短路径原则吗?的更多相关文章
- Maven依赖版本冲突的分析及解决小结
1:前言 做软件开发这几年遇到了许多的问题,也总结了一些问题的解决之道,之后慢慢的再遇到的都是一些重复性的问题了,当然,还有一些自己没有完全弄明白的问题.如果做的事情是重复的,遇到重复性问题的概率也就 ...
- java——maven依赖版本冲突
博客:maven依赖jar包时版本冲突的解决
- CDH5.16.1的maven依赖版本查询地址
1查询官网地址,提供了详细的各个版本的jar依赖版本信息 https://www.cloudera.com/documentation/enterprise/release-notes/topics/ ...
- 转:MAVEN依赖的是本地工程还是仓库JAR包?
相信大家都碰见过 maven 配置的依赖或者是 jar 包或者是工程,在开发的过程当中,我们当然需要引入的是工程,这样查看 maven 依赖的文件的时候,就能直接查看到源码. 一.本地工程依赖 举个例 ...
- Maven依赖的是本地工程还是仓库jar包?
相信大家都碰见过maven配置的依赖或者是jar包或者是工程,在开发的过程当中,我们当然需要引入的是工程,这样查看maven依赖的文件的时候,就能直接查看到源码. 一.本地工程依赖 举个例子,其架构如 ...
- Maven传递依赖的坑:父pom中dependencyManagement版本优先级高于传递依赖版本
一.由来 之前同事问了个问题,就是当前工程为spring boot项目,假设版本号为2.0.3 这个项目中依赖了一个spring boot项目依赖(先别管为啥有这么奇葩的依赖,这个版本是1.5.9). ...
- (十)Maven依赖详解
1.何为依赖? 比如你是个男的,你要生孩子,呸呸呸...男的怎么生孩子,所以你得依赖你老婆,不过也不一定咯,你也可以依赖其她妹子. 我们在平时的项目开发中也是同理,你需要依赖一些东西才能实现相应的功能 ...
- Maven依赖(转)
相同依赖级别,先加入的先依赖不同依赖级别,级别短的先依赖 version-->SNAPSHOTxxx-里程碑-->SNAPSHOT,alpha,beta,Release(RC),GA()s ...
- Maven依赖解析
本文将记录Maven工程中依赖解析机制,内容包括: Maven依赖基本结构 从仓库解析依赖的机制 依赖传递性解析实例 1. Maven依赖基本结构 上篇文章记录了Maven依赖的聚合与继承,POM中依 ...
随机推荐
- JavaScript中对象是否需要加引号?
对象的属性名是包括空字符串在内的所有字符串. 那么问题来了,我们平时定义的对象如下,是没有引号""or''的,这样不加引号有没有错呢? 答案是,加不加分情况!但加了肯定没问题... ...
- sendfile“零拷贝”和mmap内存映射
在学习sendfille之前,我们先来了解一下浏览器访问页面时,后台服务器的大致工作流程. 下图是从用户访问某个页面到页面的显示这几秒钟的时间当中,在后台的整个工作过程. 如上图,黑色箭头所示的过程, ...
- MySql Docker 主主配置
MySql 主主 准备2台Linux服务器,并且在两台服务器上,同时安装docker,国内的同学可以使用aliyun的镜像安装. curl -fsSL https://get.docker.com - ...
- Eclipse导入外部jar包的步骤
(1)首先在项目的跟目录下先建一个名字为lib的文件夹,通常外部导入的jar包都放在这个文件夹下面. (2)将需要用到的jar包复制到lib文件夹下面. (3)在项目中导入jar包 右键项目,选择Bu ...
- Android多线程消息处理机制
(1)主线程和ANR 主线程:UI线程,界面的修改只能在主线程中,其它线程对界面进行修改会造成异常.这样就解决了多线程竞争UI资源的问题. 一旦主线程的代码阻塞,界面将无法响应,这种行为就是Appli ...
- Spark Streaming 与Filnk对比分析
转:https://mp.weixin.qq.com/s/jllAegJMYh_by95FhHt0jA
- 简单做了一个代办事项列表系统 ,增删改查。 前台页面用 jquery 后台用nodejs ,数据库用的是mongdoDB 。
引入npm 第三方mongoose包连接mongoDb本地数据库todolist const mongoose = require('mongoose'); mongoose.connect('mon ...
- Facetoobject_encapsulation
面向对象程序设计思想 一.思想 处处皆对象. 当提到某一功能时,首先应该想有没有实现该功能的对象,有则调用,没有则创建类.当提到数据时,应该想到属于哪个对象. 1.求1~n的累加和 public cl ...
- linux脚本错误: line *: [: missing `]',linux编写shell脚本时的注意点
转载:https://www.cnblogs.com/bovenson/p/4548079.html 关于shell的一些注意点,粘贴自拉钩教育精选评论:测试开发核心技术 46 讲-->第6讲 ...
- 用python做youtube自动化下载器 代码
目录 项目地址 思路 流程 1. post i. 先把post中的headers格式化 ii.然后把参数也格式化 iii. 最后再执行requests库的post请求 iv. 封装成一个函数 2. 调 ...