web-dev-qa-db-ja.com

Tomcat 8.5起動中のSpringブート1.2から1.5.2へのアップグレード後、FileNotFoundException

I アップグレード Spring Boot 1.2.0から1.5.2.

アップグレード、Tomcat 8.5はスローされますFileNotFoundExceptionの間にstartupになります。

以下はの1つそれらの例外、スローされています〜10を超える類似例外です。

これらのjarファイルの目的についてはわかりません。つまり、<dependency>pom.xml。のこれらのjar

INFO: Starting Servlet Engine: Apache Tomcat/8.5.11
Apr 06, 2017 3:53:57 PM org.Apache.Tomcat.util.scan.StandardJarScanner scan
WARNING: Failed to scan [file:/C:/Users/myname/.m2/repository/com/Sun/xml/ws/jaxws-rt/2.1.7/jaxws-api.jar] from classloader hierarchy
Java.io.FileNotFoundException: C:\Users\myname\.m2\repository\com\Sun\xml\ws\jaxws-rt\2.1.7\jaxws-api.jar (The system cannot find the file specified)
    at Java.util.Zip.ZipFile.open(Native Method)
    at Java.util.Zip.ZipFile.<init>(ZipFile.Java:219)
    at Java.util.Zip.ZipFile.<init>(ZipFile.Java:149)
    at Java.util.jar.JarFile.<init>(JarFile.Java:166)
    at Java.util.jar.JarFile.<init>(JarFile.Java:130)
    at org.Apache.Tomcat.util.scan.JarFileUrlJar.<init>(JarFileUrlJar.Java:60)
    at org.Apache.Tomcat.util.scan.JarFactory.newInstance(JarFactory.Java:48)
    at org.Apache.Tomcat.util.scan.StandardJarScanner.process(StandardJarScanner.Java:338)
    at org.Apache.Tomcat.util.scan.StandardJarScanner.scan(StandardJarScanner.Java:288)
    at org.Apache.jasper.servlet.TldScanner.scanJars(TldScanner.Java:262)
    at org.Apache.jasper.servlet.TldScanner.scan(TldScanner.Java:104)
    at org.Apache.jasper.servlet.JasperInitializer.onStartup(JasperInitializer.Java:101)
    at org.Apache.catalina.core.StandardContext.startInternal(StandardContext.Java:5178)
    at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:150)
    at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1419)
    at org.Apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.Java:1409)
    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)

任意の助けをいただければ幸いです。

RootCause:

Tomcat Wikiに従って、Servlet 3.0仕様では、サーバーの起動時にJarスキャンが必要です。

Tomcatはこの目的のためにorg.Apache.Tomcat.util.scan . StandardJarScanner を使用しています。

StandardJarScannerのjavadocから。

デフォルトのJarScanner実装WEB-INF/libをスキャンディレクトリに続いて提供されたクラスローダーをスキャンし、クラスローダーの階層を処理します。この実装は、Servlet 3.0仕様の要件を満たすに十分であり、Tomcat固有の拡張機能を多数提供します。拡張機能は次のとおりです。

  • クラスローダー階層のスキャン(デフォルトで有効)すべてのファイルをテストして、それらがJARであるかどうかを確認(デフォルトで無効)

  • すべてのディレクトリをテストして、展開されたJARであるかどうかを確認します(デフォルトでは無効)

  • すべての拡張機能設定で制御可能

解決策1:スプリングブート固有。

disableこのjarスキャンを実行できます。

Application-xxx.propertiesファイルに以下のプロパティを追加して無効にしました。このプロパティは Spring Boot specific です。

# Comma-separated list of additional patterns that match jars to ignore for TLD scanning.    
server.Tomcat.additional-tld-skip-patterns=*.jar

Tomcatからの同様のプロパティここ を見つけることができます。

これらのプロパティを使用して、伝統的 Tomcat(non-spring boot)アプリケーションを構成できます。

Solution2:Spring specific

以下のようにmanifestファイルのJarScannerを無効にできます。

@Bean
public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
  return new TomcatEmbeddedServletContainerFactory() {
    @Override
    protected void postProcessContext(Context context) {
      ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
    }
  };
}

Solution3:従来のスタンドアロンTomcat:

<Context>
  ...
  <JarScanner scanManifest="false"/>
  ...
</Context>

参照: The Jar Scanner Component

Sundarajの調査結果を改善するために... TLDスキャンを完全に無効にします壊れる JSP/JSTLサポート。

問題は、クラスパス自体は問題ないことです。Tomcatのみが追加で各Jarのマニフェストファイルをスキャンします。 Jarは独自のディレクトリにあり、無意味なパスを生成します(おそらくEclipseから実行されますか?)。

したがって、JSTLでJSPを使用し続ける場合は、マニフェストスキャンのみを無効にする必要があります。

Spring Boot 2.0の場合、これをアプリケーションの構成に追加します。

  @Bean
  public TomcatServletWebServerFactory tomcatFactory() {
    return new TomcatServletWebServerFactory() {
      @Override
      protected void postProcessContext(Context context) {
        ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
      }
    };
  }
7
rustyx