Skip to content

Instantly share code, notes, and snippets.

@xkr47
Last active May 13, 2019 10:33
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xkr47/9088839 to your computer and use it in GitHub Desktop.
Save xkr47/9088839 to your computer and use it in GitHub Desktop.
Make Tomcat shut down automatically if any component fails to start up (written for tomcat version 7.0.47)
import static org.apache.catalina.Lifecycle.*;
import static org.apache.catalina.LifecycleState.*;
import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
// ...
tomcat.getServer().addLifecycleListener(new LifecycleListener() {
@Override
public void lifecycleEvent(final LifecycleEvent event) {
boolean isInit = AFTER_INIT_EVENT.equals(event.getType());
if (isInit || AFTER_START_EVENT.equals(event.getType())) {
Server server = (Server) event.getLifecycle();
boolean failed = checkServer(isInit, server);
if (failed) {
LOGGER.error("Startup failure, initiating TomCat shutdown");
triggerShutdown(isInit, server);
} else if (!isInit) {
LOGGER.info("Startup successful");
}
}
}
private boolean checkServer(final boolean isInit, final Server server) {
boolean failed = checkState(isInit, server);
for (Service service : server.findServices()) {
failed |= checkService(isInit, service);
}
return failed;
}
private boolean checkService(final boolean isInit, final Service service) {
boolean failed = checkState(isInit, service);
failed |= checkContainer(isInit, service.getContainer());
for (Connector connector : service.findConnectors()) {
failed |= checkState(isInit, connector);
}
for (Executor executor : service.findExecutors()) {
failed |= checkState(isInit, executor);
}
return failed;
}
private boolean checkContainer(final boolean isInit, final Container container) {
boolean failed = checkState(isInit, container);
for (Container child : container.findChildren()) {
failed |= checkContainer(isInit, child);
}
return failed;
}
private boolean checkState(final boolean isInit, final Lifecycle lifecycle) {
LifecycleState state = lifecycle.getState();
if (isInit ? state != NEW && state != INITIALIZED : state != STARTED) {
LOGGER.error("Component {} failed to {}: state {}", lifecycle, isInit ? "initialize" : "start", state);
return true;
}
return false;
}
private void triggerShutdown(final boolean isInit, final Server server) {
if (isInit) {
throw new RuntimeException("One or more TomCat components failed to initialize");
}
try {
server.stop();
server.destroy();
} catch (LifecycleException e) {
// ignore
}
}
});
// ...
tomcat.start();
@knatsakis
Copy link

Hi, is it ok with you if I copy this and publish it with some modifications as a maven artifact?

@xkr47
Copy link
Author

xkr47 commented Jul 2, 2014

Go ahead :) Where is it going?

@xkr47
Copy link
Author

xkr47 commented Oct 1, 2014

rev 3: In addition to checking for failures AFTER_START, also check AFTER_INIT in order to fail faster on errors during init

Copy link

ghost commented Jun 26, 2016

how do I add this to web.xml?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment