SpringBoot报错:java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;

错误:java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;

   

    最近刚刚开始用 SpringBoot 做项目,之前项目跑得好好的,就启动不起来了,后来终于解决了这个错误,这种错误出现原因很多吧,我这只能算一种原因。

    直接进入正题,我遇到的导致出现这个报错的原因:maven 项目中引入了多个版本的 servlet-api 的 jar 包,项目加载时候加载错了类(加载到 servlet-api 包中的类),getVirtualServerName 我只在SpringBoot 内嵌的 Tomcat 的包里见到了!

    解决方案:Servlet-api 3.1.0 以及之后的版本中才有 getVirtualServerName,确保项目中使用的是这个版本 3.1.0 以及之后,或者直接排除所有 Servlet-api,使用 SpringBoot内嵌的 tomcat.

 

 

一.SpringBoot 版本是 2.0.0 ,该版本下内嵌 Tomcat 的 jar 中就使用了自己的 ServletContext,官方文档中标注了该方法在 servlet-api 3.1.0 才出现,我下载了 3.1-b01 也是没有该方法的! 所以意味着我们项目如果用了 Servlet-api,那版本不得低于 3.1.0

     image

 

二. 如果知道项目引入了别的 Servlet-api,排除步骤,仅供参考,每个人都可能不一样!   

image

     可以查看项目的依赖,很明显发现了 servlet-api 2.3 的版本,注意这可能不是你自己引入的(自己引入的解决方法就不用我说了,自己删掉 dependency),别的项目引入的话,解决起来就可以参考下面的步骤。

     我也不太了解 maven 类加载机制,所以说下我觉得可能出现的几个问题,出现这个错误我认为就是加载的是 Servlet-api 3.1.0 之前的版本(和当前 SpringBoot 版本不匹配),项目中正好因为我把

axis-saaj 的依赖放在了 pom 文件依赖最前面,而 axis-saaj 依赖中正好包含了 servlet-api 的 jar, 而且用的版本是 2.3.0;  如果我将 axis-saaj 的依赖放在 pom 依赖最后面,容器又可以正常启动起来

了!

 

 

三. 我们就按照 axis-saaj 在最前面,我们不知道哪个依赖用了 servlet-api 的情况来排错! jar 包那么多,依赖那么多,这次偶然,下次呢?

POM 文件中我们右击 Diagram---》 Show Dependencies 来查看依赖图

image

 

老实说在下面这么大的网状图里找到 servlet-api 的 jar,确实有点困难,先说找到后咋办吧,在 servlet-api 上右键 exclude(快捷键 Shift+Delete),即可排除这个版本的 servlet-api;

既然找到这个这么困难,还有一种最直接的解决方案:如果项目使用的 SpringBoot 内嵌的 Tomcat,手动添加一个 Servlet-api 3.1 放到 Dependencies 里最前面,也可以解决问题.

image

 

强烈 any 一款 IDEA 插件,谁用谁知道,我也是今天才发现! Maven Helper

 Maven Helper 安装方式就不介绍了,IDEA settings  Plugin 中搜索 Maven  Helper,安装、重启就可以使用了. 直接上图,怎么解决这种 jar 冲突的问题

 

Maven Helper 使用方式:  安装成功以后,打开 POM 文件,红色箭头中内容出现就是安装成功.

 

 切换到依赖分析面板,Dependency Analyzer,然后搜索冲突的 jar,在 All Dependency 界面就可以 Exclude,很方便的找到冲突的 jar,servlet-api 2.3 排除掉,是不是很好很强大呢?

 

 

 

四. 解决方案

综上来看,最优的解决方案是在 <Dependencies> 下添加 Servlet-api 3.1 的依赖,最为直接、暴力。此外,也强烈给大家介绍了 Maven  Helper 插件排除 jar 依赖的方法

01
02
03
04
05
06
<dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
  </dependency>