Skip to content
Advertisement

Force deploy of web application to fail on Tomcat

We are researching the possibility to migrate some web JSF applications from Payara 5 to Tomcat 9 (TomEE 8). We are using Java 11 and Java EE 7/8. Our applications connect to a backend server using RMI. At the moment, with Payara 5, when the code that connects us to the backend server fails (exception is thrown because server is unavailable or credentials defined in web.xml are invalid), the deployment fails.

See this piece of code:

public class MainServlet extends HttpServlet {
  //constructor, variables etc.
  @Override
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    //read configurations from web.xml
    try {
      connectToBackendServer();
    catch (Exception e) {
      throw new UnavailableException("Cannot connect to Backend Server");
    }
  }
  //other methods
}

The above piece of code makes the deployment fail on Payara 5, but Tomcat 9 allows the deployment. With Tomcat we notice that the backend is not ok by checking the logs or by trying the front-end and getting the errors. See the below picture where the NullPointerException is thrown by our connectToBackendServer() method.

enter image description here

We are fully aware that this is not the best approach as the backend may fail later, after the successful deployment, but at least we are covering the cases when the configuration from web.xml is wrong.

Can we achieve a similar functionality with Tomcat 9(TomEE 8)?

Thank you all in advance!

..

Advertisement

Answer

Move your logic to a ServletContextListener and throw a runtime exception from contextInitialized(). On many servers this will fail the deployment and any requests to the application will return error 500. The spec does not require this exact behaviour though, so the outcome is slightly different between servers.

This is an example implementation using a ServletContextListener that fails the deployment:

package com.example;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;

@WebListener
public class ExampleServletContextListener implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent e) {
        try {
            callThatFailsAndThrowsAnException();

            catch (Exception e) {
                throw new UnavailableException("Something went very wrong - I'm bailing out.");
            }
    }

    @Override
    public void contextDestroyed(ServletContextEvent e) {
        /* Application shutdown */
    }
}

@WebListener registers the context listener with the container. If you are using an older version of JakartaEE/JavaEE and the annotation is unavailable, you can register the context listener in web.xml instead.

Advertisement