web-dev-qa-db-fra.com

APRÈS la mise à niveau de Spring boot 1.2 vers 1.5.2, FileNotFoundException lors du démarrage de Tomcat 8.5

I mis à jour Spring Boot de 1.2.0 à 1.5.2.

Après cette mise à niveau, Tomcat 8.5 lance FileNotFoundException pendant démarrage.

Ci-dessous se trouve ne de ces exceptions, Il lance plus de ~ 10 similaires exceptions.

Je n'ai aucune idée de la but de ces pots, en d'autres termes, je n'ai pas ajouté <dependency> pour ces pots en pom.xml.

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)

Toute aide serait appréciée.

19

Cause racine:

Conformément à Wiki Tomcat, la spécification Servlet 3.0 nécessite une analyse Jar au démarrage du serveur.

Tomcat utilise org.Apache.Tomcat.util.scan . StandardJarScanner à cet effet.

À partir du javadoc de StandardJarScanner .

L'implémentation par défaut de JarScanner analyse le répertoire WEB-INF/lib suivi du chargeur de classe fourni, puis élabore la hiérarchie du chargeur de classe. Cette implémentation est suffisante pour répondre aux exigences de la spécification Servlet 3.0 ainsi que pour fournir un certain nombre d'extensions spécifiques à Tomcat. Les extensions sont:

  • Analyse de la hiérarchie du chargeur de classe (activée par défaut) Test de tous les fichiers pour voir s'ils sont des fichiers JAR (désactivés par défaut)

  • Test de tous les répertoires pour voir s'ils sont des fichiers JAR éclatés (désactivé par défaut)

  • Toutes les extensions peuvent être contrôlées via la configuration .

Solution 1: spécifique à Spring Boot.

Nous pouvons désactiver cette numérisation du pot.

Je l'ai désactivé en ajoutant la propriété ci-dessous dans le fichier application-xxx.properties. Cette propriété est spécifique à Spring Boot .

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

Vous pouvez trouver des propriétés similaires à partir de Tomcat ici .

Ces propriétés peuvent être utilisées pour configurer traditionnel Tomcat ( non - Spring Boot ) applications.

Solution2: spécifique au ressort

Vous pouvez désactiver le JarScanner pour fichiers manifest comme ci-dessous.

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

Solution3: Tomcat autonome traditionnel:

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

Voir: Le composant Jar Scanner .

28

Juste pour améliorer les résultats de Sundaraj ... désactivant complètement le scan TLD cassera Support JSP/JSTL.

Le problème est que le chemin de classe lui-même est OK, seul Tomcat en plus analyse les fichiers manifestes de chaque Jar, et puisque avec Maven chaque Jar est dans son propre répertoire, cela génère des chemins sans signification (probablement à partir d'Eclipse?).

Donc, si vous souhaitez continuer à utiliser JSP avec JSTL, vous devez désactiver uniquement l'analyse du manifeste.

Pour Spring Boot 2.0, ajoutez ceci à la configuration de votre application:

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