Constructor threw exception; nested exception is java.lang.NoClassDefFoundError
在项目启动时引发这样的错误,基本都是版本不一致引起的。
先给解决思路:
1.先用idea自带的Dependency Analyzer(没有自带的,可以去插件库下载一个maven helper插件),查看依赖版本是否有冲突,然后一般是排除掉低版本的依赖
2.检查自己项目模块中的 dependencyManagement 的 dependency,是否指定了低版本的依赖,而自己项目的其他模块用了高版本的依赖。
3.检查自己项目模块中的 dependencyManagement 的 dependency 中是否有type为pom,scope为import的依赖,这种依赖里面如果也用了dependencyManagement那么将会附加到自己的项目的dependencyManagement中去,如果它的里面指定了低版本的依赖,也会有问题
注意:第3点不容易发现
原理分析: jvm在启动加载类的时候,会有双亲委派机制。
复习一下jvm加载类步骤的知识:
1.自定义加载器是否已经加载
2.系统类加载器是否已经加载
3.扩展类加载器是否已经加载
4.启动类加载器是否已经加载
5.启动类加载器能否加载
6.扩展类加载器能否加载
7.系统类加载器能否加载
8.自定义加载器能否加载
如果jvm在上述的加载阶段加载了低版本的依赖,会导致高版本的依赖不会加载。从而到运行的时候发现找不到类而报错。
最后附上一个pom例子:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>TestPom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>TestPom</name>
<description>TestPom</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 这个版本的包是有问题的,里面指定了 com/fasterxml/jackson/databind 的版本号,springboot 中的jackson版本比较高,加载的时候加载了低版本的,
导致找不到有些类,从业导致启动失败
-->
<dependency>
<artifactId>jjwt-root</artifactId>
<groupId>io.jsonwebtoken</groupId> <!-- or jjwt-gson if Gson is preferred -->
<scope>import</scope>
<type>pom</type>
<version>0.11.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>