Actualicé Spring Boot de 1.2.0 a 1.5.2 .
Después de esa actualización, Tomcat 8.5 lanza FileNotFoundException durante el inicio .
A continuación se muestra una de esas excepciones. Está lanzando más de ~ 10 excepciones similares .
No tengo idea sobre el propósito de estos frascos. En otras palabras, no agregué <dependency> para estos frascos 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)Cualquier ayuda sería apreciada.
Causa principal:
Según Tomcat Wiki , la especificación Servlet 3.0 requiere el escaneo de Jar durante el inicio del servidor.
Tomcat está usando org.apache.tomcat.util.scan. StandardJarScanner para este propósito.
Del javadoc de StandardJarScanner .
La implementación predeterminada de JarScanner escanea el directorio WEB-INF/lib seguido del cargador de clases proporcionado y luego trabaja en la jerarquía del cargador de clases. Esta implementación es suficiente para cumplir con los requisitos de la especificación Servlet 3.0 , así como para proporcionar una serie de extensiones específicas de Tomcat. Las extensiones son:
Escaneo de la jerarquía del cargador de clases (habilitado de manera predeterminada) Prueba de todos los archivos para ver si son JAR (deshabilitado de manera predeterminada)
Probando todos los directorios para ver si son JAR explotados (deshabilitados por defecto)
Todas las extensiones se pueden controlar a través de la configuración .
Solución 1: específica para Spring Boot.
Podemos deshabilitar este escaneo de jar.
Lo deshabilité agregando la siguiente propiedad en el archivo application-xxx.properties. Esta propiedad es específica de Spring Boot .
# Comma-separated list of additional patterns that match jars to ignore for TLD scanning. server.tomcat.additional-tld-skip-patterns=*.jarPuede encontrar propiedades similares de Tomcat aquí .
Estas propiedades se pueden usar para configurar aplicaciones tomcat tradicionales (arranque sin resorte).
Solución 2: Primavera específica
Puede deshabilitar el JarScanner para archivos de manifiesto como se muestra a continuación.
@Bean public EmbeddedServletContainerFactory embeddedServletContainerFactory() { return new TomcatEmbeddedServletContainerFactory() { @Override protected void postProcessContext(Context context) { ((StandardJarScanner) context.getJarScanner()).setScanManifest(false); } }; }Solución 3: Tomcat independiente tradicional:
<Context> ... <JarScanner scanManifest="false"/> ... </Context>Consulte:El componente Jar Scanner .
Solo para mejorar los hallazgos de Sundaraj... deshabilitar completamente el escaneo de TLD romperá el soporte de JSP/JSTL.
El problema es que el classpath en sí está bien, solo Tomcat escanea adicionalmente los archivos de manifiesto de cada Jar, y dado que con Maven cada Jar está en su propio directorio, eso genera rutas sin sentido (¿probablemente ejecutándose desde Eclipse?).
Entonces, si desea seguir usando JSP con JSTL, debe deshabilitar solo el escaneo de manifiesto.
Para Spring Boot 2.0, agregue esto a la configuración de su aplicación:
@Bean public TomcatServletWebServerFactory tomcatFactory() { return new TomcatServletWebServerFactory() { @Override protected void postProcessContext(Context context) { ((StandardJarScanner) context.getJarScanner()).setScanManifest(false); } }; }JarScannerFactory cargó StandardJarScanner que debemos configurar aquí , por lo que esto (para Spring Boot 2.1.8) también funciona.
import org.apache.tomcat.JarScanner; import org.apache.tomcat.util.scan.StandardJarScanner; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebContextConfiguration { @Bean public ServletContextInitializer servletContextInitializer() { return context -> context.setAttribute( JarScanner.class.getName(), new StandardJarScanner() {{ setScanManifest(false); }} ); } }