diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/ServletContextInitializerLifecycleListener.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/ServletContextInitializerLifecycleListener.java index 4bcc8496e0..bc6b3d21cf 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/ServletContextInitializerLifecycleListener.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/ServletContextInitializerLifecycleListener.java @@ -16,12 +16,12 @@ package org.springframework.boot.context.embedded.tomcat; -import javax.servlet.ServletException; - import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; import org.apache.catalina.core.StandardContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.boot.context.embedded.ServletContextInitializer; import org.springframework.util.Assert; @@ -29,10 +29,15 @@ import org.springframework.util.Assert; * Tomcat {@link LifecycleListener} that calls {@link ServletContextInitializer}s. * * @author Phillip Webb + * @author Dave Syer */ public class ServletContextInitializerLifecycleListener implements LifecycleListener { + private static Log logger = LogFactory + .getLog(ServletContextInitializerLifecycleListener.class); + private final ServletContextInitializer[] initializers; + private Exception startUpException; /** * Create a new {@link ServletContextInitializerLifecycleListener} instance with the @@ -44,6 +49,10 @@ public class ServletContextInitializerLifecycleListener implements LifecycleList this.initializers = initializers; } + public Exception getStartUpException() { + return this.startUpException; + } + @Override public void lifecycleEvent(LifecycleEvent event) { if (Lifecycle.CONFIGURE_START_EVENT.equals(event.getType())) { @@ -53,8 +62,13 @@ public class ServletContextInitializerLifecycleListener implements LifecycleList try { initializer.onStartup(standardContext.getServletContext()); } - catch (ServletException ex) { - throw new IllegalStateException(ex); + catch (Exception ex) { + this.startUpException = ex; + // Prevent Tomcat from logging and re-throwing when we know we can + // deal with it in the main thread, but log for information here. + logger.error("Error starting Tomcat context: " + + ex.getClass().getName()); + break; } } } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedContext.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedContext.java index b790682f4c..d1026b60c7 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedContext.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedContext.java @@ -28,6 +28,8 @@ import org.springframework.util.ClassUtils; */ class TomcatEmbeddedContext extends StandardContext { + private ServletContextInitializerLifecycleListener starter; + @Override public void loadOnStartup(Container[] children) { } @@ -49,4 +51,12 @@ class TomcatEmbeddedContext extends StandardContext { } } + public void setStarter(ServletContextInitializerLifecycleListener starter) { + this.starter = starter; + } + + public ServletContextInitializerLifecycleListener getStarter() { + return this.starter; + } + } diff --git a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainer.java b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainer.java index f12ea68b76..f6f7a03b5d 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainer.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainer.java @@ -77,6 +77,16 @@ public class TomcatEmbeddedServletContainer implements EmbeddedServletContainer engine.setName(engine.getName() + "-" + instanceId); } this.tomcat.start(); + Container[] children = this.tomcat.getHost().findChildren(); + for (Container container : children) { + if (container instanceof TomcatEmbeddedContext) { + Exception exception = ((TomcatEmbeddedContext) container) + .getStarter().getStartUpException(); + if (exception != null) { + throw exception; + } + } + } try { // Allow the server to start so the ServletContext is available, but stop // the connector to prevent requests from being handled before the Spring 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 089175553b..fa5cdf9a8e 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 @@ -242,8 +242,13 @@ public class TomcatEmbeddedServletContainerFactory extends */ protected void configureContext(Context context, ServletContextInitializer[] initializers) { - context.addLifecycleListener(new ServletContextInitializerLifecycleListener( - initializers)); + ServletContextInitializerLifecycleListener starter = new ServletContextInitializerLifecycleListener( + initializers); + if (context instanceof TomcatEmbeddedContext) { + // Should be true + ((TomcatEmbeddedContext) context).setStarter(starter); + } + context.addLifecycleListener(starter); for (LifecycleListener lifecycleListener : this.contextLifecycleListeners) { context.addLifecycleListener(lifecycleListener); }