文档章节

记一次jar包冲突导致项目启动失败的处理过程【java.lang.NoSuchMethodError:javax.servlet.ServletContext】

Funcy1122
 Funcy1122
发布于 04/23 18:49
字数 941
阅读 92
收藏 1

自从搞明白idea下,Jetty采用main方法启动web项目后,准备大刀阔斧地把其他web项目也改成jetty启动,不幸的是,第一个项目就遇到了问题,这里记录下整个排查流程及处理办法。

1. 异常发生

项目按idea下,Jetty采用main方法启动web项目一文中所述的进行配置后,运行,发现出现了如下异常:

java.lang.NoSuchMethodError: javax.servlet.ServletContext.getJspConfigDescriptor()Ljavax/servlet/descriptor/JspConfigDescriptor;
	at org.apache.jasper.servlet.TldScanner.scanJspConfig(TldScanner.java:158)
	at org.apache.jasper.servlet.TldScanner.scan(TldScanner.java:104)
	at org.apache.jasper.servlet.JasperInitializer.onStartup(JasperInitializer.java:103)
	......

在idea中一查javax.servlet.ServletContext,发现共有4个jar包中有这个类,分别是:

  • javax.servlet-api-3.0.1.jar
  • tomcat-embed-core-9.0.13.jar
  • javax.servlet-api-3.1.0.jar
  • servlet-api-2.4.jar

为什么会有这么多servlet-api的版本呢?主要是因为在当前的项目中,还有其他web模块,由于版本控制没做好,每个web模块使用了不同的servlet-api,此外,还有一些jar包在引入时,一不小心就连带引入了servlet-api的jar包。

所以当务之急,就是找到该web模块中的javax.servlet.ServletContext究竟来自于哪个jar包。

2. 查看类引入路径

为了找到项目中类的加载情况,需要在jvm的启动参数中,添加-verbose:class

3. 启动,查看控制台日志

再次启动,可以看到控制台已经打出了类加载信息了,包括类名、jar包位置:

[Opened C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.io.Serializable from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.Comparable from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.CharSequence from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.String from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.reflect.AnnotatedElement from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.reflect.GenericDeclaration from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.reflect.Type from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.Class from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.Cloneable from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.ClassLoader from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.System from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
[Loaded java.lang.Throwable from C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar]
......

异常中出现问题的类是javax.servlet.ServletContext,在日志搜索,发现如下记录:

[Loaded javax.servlet.ServletContext from file:/C:/Users/Administrator/.m2/repository/javax/servlet/servlet-api/2.4/servlet-api-2.4.jar]

可以看到,项目中,javax.servlet.ServletContext类是由servlet-api-2.4.jar包引入的。

关于“如何在控制台中搜索”,可以将控制台日志复制一份到文本编辑器中,如notepad++vscode等,然后使用搜索功能。

4. 使用maven定位jar包来源

目前已经知道,项目中的javax.servlet.ServletContext类是由servlet-api-2.4.jar包引入的,但servlet-api-2.4.jar是从哪里引入的呢?项目jar包是由maven来管理的,因此使用mvn命令来查找jar包引入情况,命令如下:

mvn dependency:tree -Dverbose -Dincludes=*:*servlet*

运行之后,控制台输出如下:

[INFO] com.test:test-web:war:0.0.1-SNAPSHOT
[INFO] +- javax.servlet:servlet-api:jar:2.4:provided
[INFO] +- org.eclipse.jetty:jetty-webapp:jar:9.3.2.v20150730:test
[INFO] |  \- org.eclipse.jetty:jetty-servlet:jar:9.3.2.v20150730:test
[INFO] \- org.eclipse.jetty:apache-jsp:jar:9.3.2.v20150730:test
[INFO]    +- org.eclipse.jetty:jetty-server:jar:9.3.2.v20150730:test
[INFO]    |  \- (javax.servlet:javax.servlet-api:jar:3.1.0:test - omitted for duplicate)
[INFO]    \- javax.servlet:javax.servlet-api:jar:3.1.0:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

可以看到,项目中引入的servlet-api版本是2.4,而jetty使用的servlet-api版本是3.1.0,这样就导致了jetty中使用了低版本的servlet-api,从而出现异常。

明白了问题所在,解决就很简单了,只要将项目servlet-api的版本由2.4升级到3.1.0就行了。

© 著作权归作者所有

Funcy1122

Funcy1122

粉丝 11
博文 189
码字总数 255077
作品 0
广州
后端工程师
私信 提问
一点解决版本冲突的应急思路、怎样在所有 jar 包文件中搜索冲突的方法?

原文出处:等你归去来 maven是一个很好的项目管理工具,你可以轻松的定义一个引用,从而达到使用别人写好的库的作用。且maven可以轻松地和jenkins配合,从而使打包部署变得更容易。 但是也因...

等你归去来
2018/01/15
0
0
java.lang.NoSuchMethodError 异常,神奇的东东,还望大神指点

项目启动报错,度娘说是jar包冲突,完全搞不清楚那个冲突了~~~ java.lang.NoSuchMethodError: org.springframework.beans.factory.support.DefaultListableBeanFactory.getDependencyCompar......

壹贰叁
2017/02/15
985
3
NoClassDefFoundError: org/slf4j/LoggerFactory和NoClassDefFoundError: org/apache/log4j/LogManager解决方法

1.如果运行程序出现错误:“Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory”,这是因为项目缺少slf4j-api.jar和slf4j-log4j12.jar这两个jar包导致的......

嗯哼9925
2017/12/27
0
0
部署公司后台管理系统中 关于jar包冲突的问题

部署 公司后台管理系统中 关于jar包冲突的问题 : tomcat 启动的时候报错 如下: 2014-3-10 0:56:48 org.apache.catalina.core.StandardContext listenerStart 严重: Exception sending con...

六六木木
2014/03/14
248
0
java.lang.NoSuchMethod 分析

经常遇到恼人的java.lang.NoSuchMethod,分析分析都是在什么情况下发生的。 a)用JAVA 命令运行某个Class的时候,由于Class没有提供 JAVA命令期待的main方法,这个错误经常发生在java初学者身...

晨曦之光
2012/04/25
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

Java Web 中对 ServletRequest 的一些非常规操作解决方案

1. 前言 ServletRequest 是我们搞 Java Web 经常接触的 Servlet Api 。有些时候我们要经常对其进行一些操作。这里列举一些经常的难点操作。 2. 提取 body 中的数据 前后端交互我们会在 body...

码农小胖哥
29分钟前
2
0
《Dual Encoding U-Net for Retinal Vessel Segmentation》阅读笔记-MICCAI2019

作者:Bo Wang1,2, Shuang Qiu2, and Huiguang He1,2,3 目的:Retinal Vessel Segmentation is an essential step for the early diagnosis of eye-related diseases, such as diabetes and ......

JungleKing
32分钟前
2
0
一次看懂 Https 证书认证

TLS > 传输层安全性协定 TLS(Transport Layer Security),及其前身安全套接层 SSL(Secure Sockets Layer)是一种安全协议,目的是为网际网路通信,提供安全及数据完整性保障。 如图,TLS...

极客收藏夹
46分钟前
5
0
https证书买哪家好?有哪些供应商

在选购https证书前除了要了解类型外,还需要了解https证书供应商,毕竟不同的供应商,提供的产品质量与服务也是有差异的。今天小编就为大家讲讲https证书供应商方面的内容,希望各位会喜欢。...

安信证书
48分钟前
6
0
Zuul 配置

概述:zuul底层是基于servlet,是由一系列的filter链构成。 1、路由配置 a、单例serverId映射 zuul: routes: client-a: path: /client/** serviceId: client-a 意思是...

java框架开发者
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部