javaservletsembedded-jettyjetty-8

Graceful degradation of servlets in Jetty


I'm running an embedded Jetty 8 server that loads a few *.war files at startup:

for (File aWebAppDirectory : aWebAppDirectories) {
      if (aWebAppDirectory.exists() && aWebAppDirectory.isDirectory()) {
        for (File warFile : aWebAppDirectory.listFiles(new WarFileFilter())) {            String basename = warFile.getName().replaceFirst("\\.war$", "");
         fHandlers.addHandler(new WebAppContext(warFile.getAbsolutePath(), "/" + basename));
       }
     }
   }

These war-files have some dependencies on a few classes that may or may not exist in the classpath.

Right now if one of my servlets is missing a dependency, my entire embedded Jetty service fails. (Because of NoClassDefFoundExceptions)

I need a method that allows me to catch exceptions for failing servlets and simply doesn't activate them. I'm looking for the same thing that TomCat does when a servlet fails to load: It still loads the rest.

I haven't found any solutions after some time searching on Google.

Anyone know how I can tackle this problem using embedded Jetty 8?


Solution

  • If anyone is curious how I fixed this, I simply made sure that all my servlets have a wrapper servlet that basically has no dependencies. The wrapper tries to initialize a delegate with dependencies and explicitly checks for NoClassDefFountException. If this happens, the delegate is set to null, and all calls to the wrapper interface will result in an exception. So on a high level:

    public class ServletWrapper extends HttpServlet{
      private ServletDelegate fDelegate;
      //If this is false, the delegate does not work, and we should not forward anything to it.
      private boolean fAvailable = false;
    
      public ServletWrapper(){
        try{
          fDelegate = new ServletDelegate();
          fAvailable = true;
        } catch (NoClassDefFoundError e) {
          fAvailable = false;
        }
      }
    
      @Override
      protected void doPost( HttpServletRequest request, HttpServletResponse response )
          throws ServletException, IOException {
        if ( !fAvailable || fDelegate==null ) {
          response.sendError( HttpServletResponse.SC_SERVICE_UNAVAILABLE, LSP_MISSING_ERROR_MESSAGE );
          return;
        }
    
       fDelegate.doPost(request,response);
      }
    
    }
    

    It's simple enough, and it works.