获取 NoSuchMethodError:javax.servlet.ServletContext.getVirtualServerName()

Posted

技术标签:

【中文标题】获取 NoSuchMethodError:javax.servlet.ServletContext.getVirtualServerName()【英文标题】:Getting NoSuchMethodError:javax.servlet.ServletContext.getVirtualServerName() 【发布时间】:2016-04-29 06:10:44 【问题描述】:

我在 Tomcat 8 中部署服务时遇到问题。出现以下错误:

引起:java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String; 在 org.apache.tomcat.websocket.server.WsServerContainer.(WsServerContainer.java:149) 在 org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131) 在 org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:47) 在 org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5244) 在 org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ... 10 更多

方法 getVirtualServerName 是在 Servlet 3.1 中引入的,在从我的 servlet-api jar 中提取 MANIFEST.MF 后,我得到了以下详细信息:

Specification-Title: Java API for Servlets 
Specification-Version: 3.1 
Specification-Vendor: Sun Microsystems, Inc. 
Implementation-Title: javax.servlet 

这说它有 3.1。那么这个错误还有其他原因吗?请帮忙

【问题讨论】:

你从 Eclipse 运行吗?或...请让我们了解有关您的环境、应用程序和设置的更多信息。 你确定使用Tomcat 8吗?您的帖子被标记为“tomcat7”... @AndrewRegan 对不起,这是一个错误。我编辑了。我正在使用 tomcat 8 我也在想什么,这就是为什么我问环境......你使用 pom.xml 吗?也许您应该将属性更改为<tomcat.version>xxxx</tomcat.version> to tomcat 8...? @MrSimpleMind 是的,我正在使用 POM。但我还没有声明 <tomcat.version> 。那么,如果我不声明默认情况下会采取什么措施? 【参考方案1】:

假设您在 Eclipse 中运行应用程序时出现此问题。 使用 Dependency Hierarchy 视图在 pom.xm 中搜索 servlet-api

【讨论】:

【参考方案2】:

在 Servlet 3.1 的 ServletContext 中添加了 getVirtualServerName 方法。参见java doc的方法getVirtualServerName。

这个问题有 3 个主要原因:

    您的 servlet 版本低于 3.1。

    其他一些 jar 的 servlet 版本低于 3.1。

    您的 tomcat 版本低于 8

要解决它,你可以试试下面的方法。

我。检查您的 pom.xml 以获取以下代码。

  <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>javax.servlet-api</artifactId>
       <version>3.1.0</version>
    </dependency>

如果你的 pom.xml 有上面的代码,它仍然会有这个问题。你可以做第二种方法。

二。要检查您的其他 jar,请参阅 javax.servlet-api jar。例如,org.apache.santuario 引用了javax.servlet-api jar。 pom.xml:

<dependency>  
    <groupId>org.apache.santuario</groupId>  
    <artifactId>xmlsec</artifactId>  
    <version>1.4.3</version>   
</dependency> 

但是当您查看 maven 依赖项时,它指的是 javax.servlet-api jar,其 2.3 版本比 3.1 旧。

所以你应该排除 2.3 版本。 pom.xml:

<!-- exclude servlet-api 2.3 jar-->  
<dependency>  
    <groupId>org.apache.santuario</groupId>  
    <artifactId>xmlsec</artifactId>  
    <version>1.4.3</version>  
    <exclusions>  
        <exclusion>  
            <groupId>javax.servlet</groupId>  
            <artifactId>servlet-api</artifactId>  
        </exclusion>  
    </exclusions>  
</dependency>  

<!-- servlet-api 3.1 version has getVirtualServerName() -->  
<dependency>  
    <groupId>javax.servlet</groupId>  
    <artifactId>javax.servlet-api</artifactId>  
    <version>3.1.0</version>  
</dependency> 

三。 spring boot 运行默认的 tomcat 7。所以定义你的 tomcat 版本 8 而不是 tomcat 7。所以在你的 pom.xml 中添加代码:

   <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <tomcat.version>8.5.5</tomcat.version>
    </properties>

【讨论】:

不排除传递依赖是可以的,只要包含正确的版本即可。 Maven 取图中更接近的那个。【参考方案3】:

如果你使用过这个依赖:

<dependency>
    <groupId>com.google.oauth-client</groupId>
    <artifactId>google-oauth-client-jetty</artifactId>
    <version>1.23.0</version>
</dependency>

那么请排除如下:

<dependency>
    <groupId>com.google.oauth-client</groupId>
    <artifactId>google-oauth-client-jetty</artifactId>
    <version>1.23.0</version>
    <exclusions>
        <exclusion>
            <artifactId>servlet-api</artifactId>
            <groupId>org.mortbay.jetty</groupId>
        </exclusion>
    </exclusions>
</dependency>

【讨论】:

太好了,这正是我的错误,你怎么知道的?? @Rigoxls 我记得我在使用 Google 客户端 API 和 Spring Framework 时遇到了这个问题【参考方案4】:

在经历了巨大的痛苦并筛选了所有这些 *** 答案之后,最终对我有用的唯一事情就是从 tomcat8 降级到 tomcat7。我知道这不是一个理想的解决方案,也许只是全新安装的 tomcat 解决了我的问题。如果一切都失败了,那就试试吧。

【讨论】:

【参考方案5】:

这肯定与 javax.servlet 的版本和 Tomcat 的版本有关。

就我而言,当我在没有版本的 gradle 中声明 javax.servlet 依赖项时,它就消失了。像这样——

compile('javax.servlet:servlet-api')

【讨论】:

【参考方案6】:

更新 IntelliJ 后,我在使用 maven 的 IntelliJ 上遇到此错误。

我可以使用 maven 运行测试,但不能从我的 IDE 运行。

我通过删除./ideaproject.iml 文件并重新加载项目解决了这个问题。

【讨论】:

【参考方案7】:

已解决 在我的带有 java 8 的 mac 上,从站点下载的 tomcat 并解压缩时遇到了问题。

我的问题得到了解决,因为有一个额外的 servlet-api.jar 文件正在被拾取。它来自 /Library/Java/Extensions/servlet-api.jar

为了在您的系统中找到它,您可以使用 sudo find / -name servlet-api.jar

通过在其他地方备份它来删除它。

我一直在关注这个以进行安装 https://gist.github.com/ddanailov-nmdp/c97aba2ca926b9627f6b4f7174083a32

【讨论】:

【参考方案8】:

Spring boot 将默认运行 tomcat 7,您必须在 pom.xml 中覆盖 maven build tomcat.version。请参阅下文以运行 tomcat 8.0.30

<properties>
  <tomcat.version>8.0.30</tomcat.version>
</properties>

应该可以解决您的问题。

【讨论】:

【参考方案9】:

检查您的所有 Maven(或等效)依赖项,并确保您(或很可能是另一个依赖项)没有引入可能优先于 Tomcat 8 中的 javax.servlet / servlet-api 的 3.1 之前版本。如果您已经手动部署,请确保您没有手动将任何 servlet-api JAR 复制到 Tomcat 本身中。

见:https://***.com/a/26232535/954442

【讨论】:

使用命令 mvn dependency:tree 从项目根目录的命令行中找到在 maven 中引入 servlet-api jar 的有问题的依赖项,搜索 servlet-api 的输出最有可能 2.? version ,使用 pom.xml 中的以下内容将其从依赖项中排除。 servlet-apijavax.servlet @user1412523 谢谢!这为我解决了。我的依赖是 google-oauth-client-jetty 我删除了它,因为我不需要它,它又可以工作了。 我的依赖是 hadoop-common (2.9.2) mvn dependency:tree | grep servlet-api 感谢@user1412523,这是一个非常有用的评论。我终于可以修复我的 apache fop-transcoder-allinone 2.4 依赖项,现在可以继续了。

以上是关于获取 NoSuchMethodError:javax.servlet.ServletContext.getVirtualServerName()的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/Co

java 线程“main”中的异常java.lang.NoSuchMethodError:java.util.concurrent.ConcurrentHashMap.keySet()Ljava /

JDK运行报错:Caused[0] by NoSuchMethodError: java.nio.IntBuffer.rewind()Ljava

JDK运行报错:Caused[0] by NoSuchMethodError: java.nio.IntBuffer.rewind()Ljava

Vertx JDBC NoSuchMethodError 'java.sql.Connection io.agroal.api.transaction.TransactionIntegration.g

dubbox部署到jdk1.7环境,启动:java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()(示例