diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/JasperInitializerLifecycleListener.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/JasperInitializerLifecycleListener.java new file mode 100644 index 00000000000..8b9ab4d4f03 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/JasperInitializerLifecycleListener.java @@ -0,0 +1,47 @@ +package org.springframework.boot.context.embedded.tomcat; + +import org.apache.catalina.LifecycleEvent; +import org.apache.catalina.LifecycleListener; +import org.springframework.boot.context.embedded.ServletContextInitializer; +import org.springframework.util.ClassUtils; + +/** + * Tomcat {@link LifecycleListener} to initialize Jasper by calling the + * `JasperInitializer` used in Tomcat 8. + * + * @author Phillip Webb + */ +class JasperInitializerLifecycleListener implements LifecycleListener { + + private static final String JASPER_INITIALIZER_CLASS = "org.apache.jasper.servlet.JasperInitializer"; + + private final ServletContextInitializerLifecycleListener delegate; + + public JasperInitializerLifecycleListener() { + ServletContextInitializer initializer = getJasperInitializer(); + if (initializer != null) { + this.delegate = new ServletContextInitializerLifecycleListener(initializer); + } + else { + this.delegate = null; + } + } + + @Override + public void lifecycleEvent(LifecycleEvent event) { + if (this.delegate != null) { + this.delegate.lifecycleEvent(event); + } + } + + private ServletContextInitializer getJasperInitializer() { + try { + Class jasperClass = ClassUtils.forName(JASPER_INITIALIZER_CLASS, null); + return (ServletContextInitializer) jasperClass.newInstance(); + } + catch (Exception ex) { + return null; + } + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java index a4491caed7b..2fd2463c80b 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java @@ -230,6 +230,7 @@ public class TomcatEmbeddedServletContainerFactory extends ServletContextInitializer[] initializers) { context.addLifecycleListener(new ServletContextInitializerLifecycleListener( initializers)); + context.addLifecycleListener(new JasperInitializerLifecycleListener()); for (LifecycleListener lifecycleListener : this.contextLifecycleListeners) { context.addLifecycleListener(lifecycleListener); } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java index f87ab969182..f59040fa4d8 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedWebappClassLoader.java @@ -16,7 +16,11 @@ package org.springframework.boot.context.embedded.tomcat; +import java.net.URL; + import org.apache.catalina.loader.WebappClassLoader; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Extension of Tomcat's {@link WebappClassLoader} that does not consider the @@ -28,6 +32,9 @@ import org.apache.catalina.loader.WebappClassLoader; */ public class TomcatEmbeddedWebappClassLoader extends WebappClassLoader { + private static final Log logger = LogFactory + .getLog(TomcatEmbeddedWebappClassLoader.class); + public TomcatEmbeddedWebappClassLoader() { super(); } @@ -78,6 +85,14 @@ public class TomcatEmbeddedWebappClassLoader extends WebappClassLoader { return (resultClass); } + @Override + protected void addURL(URL url) { + // Ignore URLs added by the Tomcat 8 implementation (see gh-919) + if (logger.isTraceEnabled()) { + logger.trace("Ignoring request to add " + url + " to the tomcat classloader"); + } + } + private Class loadFromParent(String name) { if (this.parent == null) { return null;