How to abort Tomcat startup upon exception in Serv

2020-08-20 07:05发布

问题:

I have a class implementing ServletContextListener that loads some resources upon startup.

Those resources are critical to the application in a way that I would like to fail the whole startup when some bad event happens in my logic.

Is there any command I can execute from inside the ServletContextListener.contextInitialized() method to stop and fail the whole Tomcat startup?

回答1:

Try specifying:

-Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE=true

in your java runtime options, quoting official documentation:

If true, the server will exit if an exception happens during the server initialization phase.

If not specified, the default value of false will be used.

UPDATE:

If you want to do this by code, will System.exit() work?

public class FailFastListener implements ServletContextListener {
    
    private static final Logger log = LoggerFactory.getLogger(FailFastListener.class);
    
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        try {
            //initialization
        } catch(Exception e) {
            log.error("Sooo bad, shutting down", e);
            System.exit(1);
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }
}

You can use decorator pattern to wrap existing listeners without cluttering them. Not sure how will Tomcat react thou...



回答2:

If you want to stop Tomcat because your webapp failed to deploy, I assume you don't have other apps deployed to tomcat. In that case why don't you build this app as a standalone webapp with embedded Tomcat/Jetty? This way, as long as your webapp does not start properly, the embedded server will shutdown too.

To me, it looks like you're focused on ServletContextListener to tackle a problem that is not what ServletContextListener is meant for.

Do not use System.exit() because it will kill server that might me running other deployed apps. If it's ok because you know there will never be other apps (and you don't want to), then make a standalone webapp. This bad practice is listed in CWE as a potential weakness: CWE-382

Just a hint: spring boot facilitates the effort of building a standalone webapp with embedded server. See this guide: https://spring.io/guides/gs/spring-boot/

Good article explaining why this is probably what you're looking for: http://www.beyondjava.net/blog/application-servers-sort-of-dead/