Catch application exception in tomcat starter thread and rethrow
Fixes gh-1088
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user