(一)关于类文件具有错误的版本55.0,应为52.0
如上图所示,IDEA运行时发生了异常,百度之后查到了答案,在这里记录一下:
以下内容是百度的答案:
原因:
上面报错中的55.0是JDK11使用的类文件格式(class file format)的版本号
提示的意思是当面项目使用的类文件格式版本比某个依赖包使用的类文件格式版本低
实际就是指当前项目使用的JDK版本比某个依赖包使用的JDK版本低
例如,新版Jetty(10.0.0或以上版本)使用了JDK11,一旦项目是使用JDK1.8并引用了新版Jetty组件就会报错,只能使用Jetty9.4.44或以下版本
方法1:
修改项目使用的JDK版本为大于或等于依赖包的版本
File -> Project Structure -> Project -> Project SDK
方法2:
修改依赖包的版本号,一般旧版的组件使用的是旧版JDK
例如,修改Maven配置文件pom.xml中对应依赖包的<dependency><version></version></dependency>值
(二)关于jar包冲突:
我们项目开发中经常会遇到jar包冲突的情况,在这里分享一下关于jar包冲突的内容。
jar包冲突产生的原因是如果我们引入了2个jar包,而这2个jar包分别又有传递依赖,比如X->H->K(1.0.0),Y->H->J->K(1.0.1),这时候K包有1.0.0和1.0.1两个版本。
依据Maven中的依赖传递原则,最短路径优先原则和最先声明优先原则(即路径长短一样,优先选最先声明的那个),也就是classpath只会依赖一个版本,由于这两个路径长度不一样,根据最短路径原则,最终依赖的是1.0.0版本。
如果J包用到了K包1.0.1版本中新的方法的时候,当运行到对应代码逻辑的时候会报NoSuchMethodError,该方法原本应该依赖的是1.0.1版本,由于jar冲突了,maven选择了1.0.0版本。1.0.0版本中没有这个新的方法(method),因此会报错。
注意:有些jar包冲突并不会发生运行时异常,比如日志slf4j包冲突,就是导致比如mybatis打印sql的日志无法打印到控制台。只有高版本的jar没有向下兼容,或者新增了某些低版本没有的API才可能导致运行时报错。
着手解决jar包冲突
因为知道了是jar包冲突,所以我准备用mvn dependency:tree -Dverbose命令在控制台看一下maven依赖树,(如果是本地环境,还可以下载一个依赖分析神器的插件Maven Helper,具体步骤:点击左上角file->settings->plugins->搜索Maven Helper->install)但是这里使用命令的时候又遇到了一个问题,因为我是临时使用这个电脑,然后从同事那里导入了这个项目,想当然地以为电脑上配置了maven的环境变量。 然而,在输入命令的那一刻就出现了“mvn不是内部或外部命令”提示,于是我又去配置了maven的环境变量。
配置环境变量的具体步骤:
找到桌面上的此电脑->属性->高级系统设置->环境变量
点击新建添加一个MAVEN_HOME
点击上方用户变量那里的编辑,把maven的路径添加到path对应的值的所有路径名的后面。
之后点击确定,重启idea即可。
这个时候就可以使用mvn命令了 ,继续执行mvn dependency:tree -Dverbose命令,可以看到有很多冲突和重复的依赖。具体如下:
- “
+-
”符号:表示该包后面还有其它依赖包。 - “
\-
”表示:该包后面不再依赖其它jar
包。 末尾出现omitted for conflict withXX表示由于与XX有冲突而被省略,末尾出现omitted for duplicate表示有重复。 omitted for conflict with解决:
对于冲突包的版本,想生效谁,就把除它以外的版本给exclude掉即可,具体如下。
尝试版本锁定法
当然如果关于这一个jar包冲突比较多,而我们只用其中一个版本的情况下, 就会导致需要exclude去排除的有很多,很麻烦且在pom文件中也有体现,不美观。
我们可以使用版本锁定法,如果我们的项目有父级pom的话,我们想指定哪个版本就在父pom文件中定义即可,没有父级pom那就在本工程pom文件定义即可。
具体如下,把jar包名和版本号改成自己的就行:
<dependencyManagement>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>4.4.2</version>
</dependency>
</dependencyManagement>
因为版本锁定法打破了两个依赖传递的原则,优先级是最高的,版本锁定后,在maven树上,关于该jar包的版本都统一为4.4.2了。这也侧面印证了版本锁定法的一个好处:它并不排除jar包,而且显示的所有之前版本不一致的jar包都变成了统一规定的版本。
omitted for duplicate解决
我们将重复定义的jar包删掉即可,当然我们还可以使用mvn dependency:analyze-duplicate来分析重复定义的依赖。