web-dev-qa-db-ja.com

Spring MVCアプリケーションの実行中にSpring BootでNoSuchMethodError:javax.servlet.ServletContext.addServletを取得する

Springブートを使用してSpring MVCアプリケーションを実行しようとすると、以下の例外が発生します...

ContainerBase: A child container failed during start
Java.util.concurrent.ExecutionException: org.Apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
    at Java.util.concurrent.FutureTask.report(FutureTask.Java:122)
    at Java.util.concurrent.FutureTask.get(FutureTask.Java:188)
    at org.Apache.catalina.core.ContainerBase.startInternal(ContainerBase.Java:1123)
    at org.Apache.catalina.core.StandardHost.startInternal(StandardHost.Java:799)
    at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:150)
    at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1559)
    at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1549)
    at Java.util.concurrent.FutureTask.run(FutureTask.Java:262)
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145)
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615)
    at Java.lang.Thread.run(Thread.Java:745)
Caused by: org.Apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].StandardContext[]]
    at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:154)
    ... 6 more
Caused by: Java.lang.NoSuchMethodError: javax.servlet.ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)Ljavax/servlet/ServletRegistration$Dynamic;
    at org.springframework.boot.context.embedded.ServletRegistrationBean.onStartup(ServletRegistrationBean.Java:166)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.Java:214)
    at org.springframework.boot.context.embedded.Tomcat.ServletContextInitializerLifecycleListener.lifecycleEvent(ServletContextInitializerLifecycleListener.Java:54)
    at org.Apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.Java:117)
    at org.Apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.Java:90)
    at org.Apache.catalina.core.StandardContext.startInternal(StandardContext.Java:5355)
    at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:150)
    ... 6 more
38
Arghya Sadhu

クラスのロード元を調べたい場合は、試してください

Java -verbose:class -jar foo.jar | grep javax.servlet.ServletContext

どこ foo.jarは、GradleまたはMavenによって生成されるファットJARです。たとえば、ServletContextクラスは古いservlet-api MavenまたはGradleの依存関係ではなく、JDK拡張ディレクトリのJAR。

コマンドの出力は次のようになります...

$ Java -verbose:class -jar build/libs/foo-0.2.3.jar | grep javax.servlet.ServletContext
[Loaded javax.servlet.ServletContext from jar:file:.../build/libs/foo-0.2.3.jar!/lib/javax.servlet-api-3.1.0.jar!/]
[Loaded javax.servlet.ServletContextListener from jar:file:.../build/libs/foo-0.2.3.jar!/lib/javax.servlet-api-3.1.0.jar!/]
[Loaded javax.servlet.ServletContextAttributeListener from jar:file:.../build/libs/foo-0.2.3.jar!/lib/javax.servlet-api-3.1.0.jar!/]
27

推移的なservlet-api依存関係を除外して解決しました。

私の場合、それはcom.github.isrsal:spring-mvc-loggerでした

<dependency>
    <groupId>com.github.isrsal</groupId>
    <artifactId>spring-mvc-logger</artifactId>
    <version>0.2</version>
    <exclusions>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>
25
amuniz

gradleソリューション。

Lib jarに同様の問題があり、何らかの理由でjavax.servlet.ServletContextの古いバージョンが持ち込まれました。

Libモジュールのbuild.gradleを編集して修正しました:

configurations {
    provided.all*.exclude group: 'javax.servlet'
}
21
kumetix

servlet-apiを除外しても解決できなかった他の人のために、代替手段を次に示します。

Spring BootのデフォルトはTomcat 8です。異なるバージョンのTomcatを実行していて、このエラーを修正する場合は、Tomcatバージョンをpomプロパティに追加してください。

<properties>
    <Tomcat.version>7.0.63</Tomcat.version>
</properties> 

tests(gradle + spockを使用)の間にスプリングブートサーバーを起動しようとしたときに、この問題が発生しました。私はwiremockライブラリに問題をトレースしました。

これにより修正されました。

testCompile('com.github.tomakehurst:wiremock:1.58') {
    exclude module: 'servlet-api' // this exclude fixed it
}

ご参考までに

gradle dependencies

ショー(要約):

\--- com.github.tomakehurst:wiremock:1.58
     +--- org.mortbay.jetty:jetty:6.1.26
          +--- org.mortbay.jetty:jetty-util:6.1.26
          \--- org.mortbay.jetty:servlet-api:2.5-20081211

古代(2008)org.mortbay.jetty:servlet-api jarには、バージョン1.3.2のスプリングブートと互換性のないServletContextのバージョンが含まれています(少なくとも1.2.6までは正常に機能しました)。

6
Bohemian

これは、展開サーバーでのみ、スプリングブートwebappにありました(ローカルマシンで正常に実行されていました)。以下を追加して解決します:

<dependencies>
<!-- … -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-Tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<!-- … -->

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html

6
Shoham

私はGradleを使用していましたが、私のために働いたもの:

configurations {
    all*.exclude group: '', module: 'servlet-api'
}

必要な方法で依存関係ツリーをトリミングしました。

5
kkonrad

Spring-bootを使用してHadoop 2.7.2で実行していましたが、次のHadoop依存関係はjavax.servletを使用しているため、組み込みTomcatバージョンを起動できませんでした。 POMの除外項目の下問題を修正

                                    <dependency>
                                    <groupId>org.Apache.hadoop</groupId>
                                    <artifactId>hadoop-hdfs</artifactId>
                                    <version>2.7.2</version>
                                    <exclusions>
                                        <exclusion>
                                            <artifactId>servlet-api</artifactId>
                                            <groupId>javax.servlet</groupId>
                                        </exclusion>
                                    </exclusions>
                                </dependency>
                                <dependency>
                                    <groupId>org.springframework.data</groupId>
                                    <artifactId>spring-data-hadoop-boot</artifactId>
                                    <version>2.3.0.RELEASE-hadoop26</version>
                                    <exclusions>
                                        <exclusion>
                                            <artifactId>servlet-api</artifactId>
                                            <groupId>javax.servlet</groupId>
                                        </exclusion>
                                    </exclusions>
                                </dependency>

                                <dependency>
                                    <groupId>org.Apache.hadoop</groupId>
                                    <artifactId>hadoop-common</artifactId>
                                    <version>2.7.2</version>
                                    <exclusions>
                                        <exclusion>
                                            <artifactId>slf4j-log4j12</artifactId>
                                            <groupId>org.slf4j</groupId>
                                        </exclusion>
                                        <exclusion>
                                            <artifactId>servlet-api</artifactId>
                                            <groupId>javax.servlet</groupId>
                                        </exclusion>
                                    </exclusions>
                                </dependency>
5

このソリューションによると、 https://stevewall123.wordpress.com/2015/04/17/spring-boot-application-and-Tomcat-error-a-child-container-failed-during-start/

「Tomcat.version」プロパティを設定して、Tomcatバージョンを変更できます。

ext['Tomcat.version'] = '7.0.63' //my version of Tomcat

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
}

その記事の著者に感謝します。

乾杯:)

3
thyzz

STSを使用していて、プロジェクトにGroovyライブラリを追加している場合(プロジェクトプロパティ-> Java Build Path-> Libraries))、[いいえ、groovyのみを含める]を選択してください。 -all」オプション。「Yes、include groovy-all and bsf.jar ...、servlet-2.4.jar」の他のオプションは、この問題を引き起こす埋め込みTomcat8クラスと競合するservlet-2.4.jarを追加します。

2
ghostcoder007

プロジェクトでJettyを使用していますが、同じエラーが発生しました。私の簡単な解決策は、埋め込まれたTomcatをMaven依存関係から除外することでした。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-ws</artifactId>
    <version>1.2.0.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-Tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
2
Olga

私がクラスパスに何らかの形で入っていることを知っていることを除いて、問題のある参照を追跡できませんでしたので、Eclipseを使用する怠zyな開発者のための私の2セントです:

プロジェクトツリーの下のmaven依存関係のリストをスクロールダウンし(通常Java Resources-> Libraries-> Maven Dependencies))、パッケージJARから除外する問題のある追加jarを追跡し、右クリックしますその上で-> Mavenを選択-> Maven Artifactを除外!ほら-自動的に、それを参照する依存関係のすぐ下に除外が追加されます。

私のBTWはjcifsでした...

        <dependency>
        <groupId>org.codelibs</groupId>
        <artifactId>jcifs</artifactId>
        <version>1.3.18.2</version>
        <exclusions>
            <exclusion>
                <artifactId>servlet-api</artifactId>
                <groupId>javax.servlet</groupId>
            </exclusion>
        </exclusions>
    </dependency>

幸運を!

2
baraka

mvn dependency:treeはクラスパス上のservlet-api.jarを明らかにしませんでしたが、プロジェクト(Eclipseで)を右クリックしてBuild Path/Configure Build Pathは、デフォルトのワークスペースJRE、JDK 1.7.0_51がそのjarをそのjre/lib/extディレクトリ(少なくとも私のインストール)。クラスパスから削除しようとしましたが、失敗しました。 @Pedroの ソリューション は、Tomcatバージョンを7に強制することで機能しました。 Java 7:JDK 1.7.0_79。の最新バージョンをインストールしました。

1

私もこのエラーに直面しました。 Maven/Spring MVC/Spring Bootプロジェクトがあります。 IntelliJをIDEとして使用しています。POM.xmlに新しい依存関係を追加するたびに、IDEは.imlファイルを変更します(予想どおり)奇妙なことに、次の行がファイルの先頭に移動します。

<orderEntry type="library" name="Java EE 6-Java EE 6" level="project" />

それが起こると、私のプロジェクトはコンパイルされず、同じエラーが表示されます:

Java.lang.NoSuchMethodError:javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;

Java EEのorderEntryを一番下に戻すだけで、エラーがなくなり、もう一度コンパイルできます。

1
Bipin Butala

迅速な解決策として、servlet-api.jarをlibから手動で削除し、アプリケーションをビルドして動作しますが、理想的にはKumetixが示唆するように、クラスパスでロードする依存関係まで精査する必要があります。

0
road2victory