使用java-jar和Tomcat8从spring启动getVirtualServerName。STS运行良好

使用java-jar和Tomcat8从spring启动getVirtualServerName。STS运行良好,java,tomcat,spring-boot,Java,Tomcat,Spring Boot,我有一个SpringBoot应用程序,在eclipse中运行良好。当我构建它并从命令行运行它时,它会失败并出现异常 问题似乎是servlet版本不匹配,但我不明白为什么 还需要注意的是,我没有使用Maven或Gradle-( 我的运行命令: java-jar Demo.jar 例外情况: Sep 15, 2015 7:30:24 PM org.apache.catalina.core.StandardContext listenerStart SEVERE: Exception sending

我有一个SpringBoot应用程序,在eclipse中运行良好。当我构建它并从命令行运行它时,它会失败并出现异常

问题似乎是servlet版本不匹配,但我不明白为什么

还需要注意的是,我没有使用Maven或Gradle-(

我的运行命令:

java-jar Demo.jar

例外情况:

Sep 15, 2015 7:30:24 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.apache.tomcat.websocket.server.WsContextListener
java.lang.NoSuchMethodError:
javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
at org.apache.tomcat.websocket.server.WsServerContainer.<init>(WsServerContainer.java:147)
at org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131)
at org.apache.tomcat.websocket.server.WsContextListener.contextInitialized(WsContextListener.java:39)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4729)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
2015年9月15日晚上7:30:24 org.apache.catalina.core.StandardContext listenerStart
严重:向类org.apache.tomcat.websocket.server.WsContextListener的侦听器实例发送上下文初始化事件时发生异常
java.lang.NoSuchMethodError:
servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
位于org.apache.tomcat.websocket.server.WsServerContainer.(WsServerContainer.java:147)
位于org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131)
位于org.apache.tomcat.websocket.server.WsContextListener.contextInitialized(WsContextListener.java:39)
位于org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4729)
位于org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)
位于org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
位于org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)
位于org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)
在java.util.concurrent.FutureTask.run(FutureTask.java:266)处
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
运行(Thread.java:745)
My MANIFEST.MF在类路径中设置了这些tomcat jar。它们存在并且可以访问

。/../JavaJars.461248/lib/tomcat-embed-core-8.0.23.jar
../../JavaJars.461248/lib/tomcat-embed-el-8.0.23.jar
../../JavaJars.461248/lib/tomcat-embed-logging-juli-8.0.23.jar
../../JavaJars.461248/lib/tomcat-embed-websocket-8.0.23.jar

这些位置看起来有点奇怪,但是文件在那里。如果我删除了,我会得到一个与没有servlet相关的启动异常

我认为getVirtualServerName在servlet的3.1版本中,我认为这些版本的tomcat都有。这些相同的文件在我的eclipse类路径中,这让人感到困惑,而且我没有遇到任何问题


对我缺少的内容有什么建议吗?

Andy在评论中回答。详细的类加载让我看到了问题。

小心spring boot插件,因为它似乎添加到了类路径提供的范围依赖项中。我在Embedded tomcat启动web套接字上下文时遇到了这个异常

在我的例子中,问题只会在使用springboot:run目标时发生

原因是gwt-user.jar包捆绑了一个旧的

public interface ServletContext {
不使用该方法的API

另一方面,tomcat希望加载的ServletContext类是tomcat-embedded-core-8.0.30.jar的一部分,它是spring boot默认配置的一部分

解决此问题的方法是使用以下工具调整spring引导插件:

                      <excludes>
                            <exclude>
                                <groupId>com.google.gwt</groupId>
                                <artifactId>gwt-user</artifactId>
                            </exclude>
                        </excludes>

com.google.gwt
gwt用户
生产jar和netbeans调试类运行得完美无缺,只有使用插件时才会发生此错误


在任何情况下,这都是典型的classpath vodoo异常。如果您有一个好的IDE,请查找类型并在所有依赖项中搜索ServletContext类。如果您找到不同的API,那么。

您的应用程序必须从其他地方加载
ServletContext
类。尝试使用
-verbose:class运行您的应用程序de>。输出将告诉您它来自何处。另外,有没有办法将tomcat版本设置为启动参数或代码?我知道您可以使用maven属性进行设置,但我没有使用maven或gradle。我这样问是因为在部署时可能无法从类路径中删除servlet jar。不,Spring Boot将使用任何版本Tomcat的n在类路径上(严格地说,无论Tomcat的哪个版本首先出现在类路径上)。