scalajettyscalatra

Have Scalatra exit if LifeCycle added with Context.setInitParameter throws exception


I want a Scalatra servlet to exit if initialization fails so that upstart/systemd/whatever can restart it on failure.

Drawing from examples on the web, we have a LifeCycle that does some initialization, but occasionally fails

class Bootstrap extends LifeCycle {
  override def init(context: ServletContext) {
    throw new RunTimeException("foo")
  }
}

Our initialization procedure is otherwise pretty typical

val server = new Server(port)
val context = new WebAppContext()
context setContextPath("/")
context.setResourceBase("src/lab/src/main/webapp")
context.setInitParameter(ScalatraListener.LifeCycleKey, "Bootstrap")

context.addEventListener(new ScalatraListener)
server.setHandler(context)

server.start
server.join

Is there a way to make the server stop on an initialization exception without putting a try block around the bootstrap code and calling stop manually.

Thanks


Solution

  • The short answer is no.

    The slightly longer answer is that your LifeCycle (ScalatraBootstrap) init is already wrapped in a try/catch block, you can see that in the source for ScalatraListener. But it just throws an exception.

    There's two reasons for this;

    First -- The bootstrap is designed to bootstrap more than one servlet, if one fails, the expected condition is the rest still come up.

    Second -- even if you only stand up one servlet, the reason your shutdown code isn't called is actually defined in the servlet spec;

    2.3.2.1 Error Conditions on Initialization

    During initialization, the servlet instance can throw an UnavailableException or a ServletException. In this case, the servlet must not be placed into active service and must be released by the servlet container. The destroy method is not called as it is considered unsuccessful initialization.