Catch application exception in tomcat starter thread and rethrow

Fixes gh-1088
pull/1118/head
Dave Syer 11 years ago
parent 6c4d9d7190
commit d842446186

@ -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;
}
}
}

@ -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;
}
}

@ -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

@ -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);
}

Loading…
Cancel
Save