女朋友他们项目用了 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. JavaScript中对象是否需要加引号?

    对象的属性名是包括空字符串在内的所有字符串. 那么问题来了,我们平时定义的对象如下,是没有引号""or''的,这样不加引号有没有错呢? 答案是,加不加分情况!但加了肯定没问题... ...

  2. sendfile“零拷贝”和mmap内存映射

    在学习sendfille之前,我们先来了解一下浏览器访问页面时,后台服务器的大致工作流程. 下图是从用户访问某个页面到页面的显示这几秒钟的时间当中,在后台的整个工作过程. 如上图,黑色箭头所示的过程, ...

  3. MySql Docker 主主配置

    MySql 主主 准备2台Linux服务器,并且在两台服务器上,同时安装docker,国内的同学可以使用aliyun的镜像安装. curl -fsSL https://get.docker.com - ...

  4. Eclipse导入外部jar包的步骤

    (1)首先在项目的跟目录下先建一个名字为lib的文件夹,通常外部导入的jar包都放在这个文件夹下面. (2)将需要用到的jar包复制到lib文件夹下面. (3)在项目中导入jar包 右键项目,选择Bu ...

  5. Android多线程消息处理机制

    (1)主线程和ANR 主线程:UI线程,界面的修改只能在主线程中,其它线程对界面进行修改会造成异常.这样就解决了多线程竞争UI资源的问题. 一旦主线程的代码阻塞,界面将无法响应,这种行为就是Appli ...

  6. Spark Streaming 与Filnk对比分析

    转:https://mp.weixin.qq.com/s/jllAegJMYh_by95FhHt0jA

  7. 简单做了一个代办事项列表系统 ,增删改查。 前台页面用 jquery 后台用nodejs ,数据库用的是mongdoDB 。

    引入npm 第三方mongoose包连接mongoDb本地数据库todolist const mongoose = require('mongoose'); mongoose.connect('mon ...

  8. Facetoobject_encapsulation

    面向对象程序设计思想 一.思想 处处皆对象. 当提到某一功能时,首先应该想有没有实现该功能的对象,有则调用,没有则创建类.当提到数据时,应该想到属于哪个对象. 1.求1~n的累加和 public cl ...

  9. linux脚本错误: line *: [: missing `]',linux编写shell脚本时的注意点

    转载:https://www.cnblogs.com/bovenson/p/4548079.html 关于shell的一些注意点,粘贴自拉钩教育精选评论:测试开发核心技术 46 讲-->第6讲 ...

  10. 用python做youtube自动化下载器 代码

    目录 项目地址 思路 流程 1. post i. 先把post中的headers格式化 ii.然后把参数也格式化 iii. 最后再执行requests库的post请求 iv. 封装成一个函数 2. 调 ...