从github上拉了一份代码本地运行报错,
Caused by: java.lang.ClassNotFoundException

提出问题
这里解释一下编译和打包的含义,编译针对的是我们项目写的java源码,显然不包括依赖的jar,编译完毕之后java源码就变成了可以被执行class字节码,而打包的含义是,将字节码打包成一个可执行的jar包 ,我们依赖的jar包本身就是字节码,不在编译范围
那么我们知道为什么ClassNotFoundException会在运行时才会被发现之后继续提出问题
这里要说一个依赖传递的概念
依赖传递的意思是项目A依赖项目B,项目B依赖项目C,在使用项目A时,就会加载项目B,这样传递依赖就会把项目C,D,E等等加载进来。其中B是A的直接依赖,C是A的间接依赖
例如:A项目依赖B(版本为1.1),C项目也依赖B(版本为1.2),假如现在有一个项目同时依赖项目A和项目B,那么他就会导入两个版本的B,由于B的两个版本不同,这里就会导致冲突,这个时候就需要exclusions来解决冲突,不过maven也有一个机制会避免两个都加载进去,
下面先介绍maven的依赖调节原则:
1,第一原则:路径近者优先原则
A→B→C→X(1.1)
D→E→X(1.2)
使用X(1.2),因为其路径更近
2,第二原则:第一声明者优先原则
A→B→X(1.1)
C→D→X(1.2)
使用X(1.1),因为其先声明
maven会先根据第一原则判断,若路径相等,再根据第二原则判断
知道了依赖传递后举个例子,我们当前项目是A ,-> 表示依赖
A->B->C(1.1)
同时A->C(0.5)
那么根据路径近有效,我们整个项目所使用的就是0.5版本的C。而B需要使用C种的某个类在0.5种没有。那么就会发生编译本问题,运行时报错ClassNotFoundException**,这就是maven冲突**
例如我这个报错
Caused by: java.lang.ClassNotFoundException: com.alibaba.spring.context.OnceApplicationContextEventListener
根据包路径确认冲突jar包是spring-context-support
比如我们的项目引入A的依赖C为1.1版本,引入的B会在内部依赖C的1.0版本,那么Dependency Analyzer插件会出现依赖冲突提示,会提示B引入的C的1.0版本和当前选用的C的1.1版本冲突因而被忽略(1.0 omitted for conflict with 1.1)。因此我们主要关注的就是omitted 这种情况

像我这个例子,dubbo依赖的spring-context-support1.0.11被替换冲突替换成了1.0.5
根据依赖层路径可以看出来,最下面这个是路径最短,那么起决定性作用的就是这个了,如果将其remove或者exclude掉,**那么根据,路径相同,先生命优先,**版本就会被替换成为1.0.11,我本地的问题到这里旧被解决了。