场景描述:
maven+springboot项目,启动的时候出现异常,具体信息如下:
Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_181]
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_181]
at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_181]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:613) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:524) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:510) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:247) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
... 17 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServletRequest
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_181]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_181]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_181]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_181]
... 24 common frames omitted
NoClassDefFoundError和ClassNotFoundException一般是运行时Class未加载到时出现的异常
ClassNotFoundException 1 | NoClassDefFoundError 2 |
---|---|
从java.lang.Exception继承,是一个Exception类型 | 从java.lang.Error继承,是一个Error类型 |
当动态加载Class的时候找不到类会抛出该异常 | 当编译成功以后执行过程中Class找不到导致抛出该错误 |
一般在执行Class.forName()、ClassLoader.loadClass()或ClassLoader.findSystemClass()的时候抛出 | 由JVM的运行时系统抛出 |
那么一定是运行时没有加载到servlet-api.jar,由于是web项目用的tomcat部署,一般都是tomcat中;检查maven配置
<groupId>com.geekq</groupId>
<artifactId>miaosha</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。
相当于compile,但是打包阶段做了exclude操作-->
<scope>provided</scope>
</dependency>
这里把内置的tomcat生命周期配置成provided,造成运行时找不到class,调整后:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>