urir
urir

Reputation: 2015

How to abort Tomcat startup upon exception in ServletContextListener?

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?

Upvotes: 11

Views: 6954

Answers (2)

L. Holanda
L. Holanda

Reputation: 4631

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 the server that might be 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/

Upvotes: 1

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340733

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 pattern to wrap existing listeners without cluttering them. Not sure how will Tomcat react thou...

Upvotes: 12

Related Questions