Last active
May 13, 2019 10:33
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
Go ahead :) Where is it going?
rev 3: In addition to checking for failures AFTER_START, also check AFTER_INIT in order to fail faster on errors during init
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
Hi, is it ok with you if I copy this and publish it with some modifications as a maven artifact?