6

Sometimes during development, something gets broken which cause the spring context to fail loading. The problem is that sometimes the error is just in some bean(s), but the rest of the webapp is partially loading, and then you get some weird behaviors.

Is there a known way to make Spring stop the server process in case something bad happened? like some bean failed injection, or some NPE happened in some PostConstruct or something.

Something like stopOnError=true in web.xml.

Elad Tabak
  • 2,317
  • 4
  • 23
  • 33
  • 2
    Actually this is an default behavior of spring. How are you loading your context? – AlexR Aug 17 '14 at 08:40
  • What do you mean? I know this is the default behavior. I was wondering if there's something I can use to change it. The context is loaded using web.xml with tomcat. – Elad Tabak Aug 17 '14 at 09:39
  • I mean that default behavior is what you actually want. I have never seen half made spring context. If even 1 bean of 1000 fails the whole context fails, the web app is not deployed and therefore unavailable. – AlexR Aug 17 '14 at 09:42
  • But the server is still loading, and if you have other webapps, they will load and will attempt to communicate with each over (messages etc.) and will fail. Maybe this is a unique case... I would like a fatal error that will fail the entire server. – Elad Tabak Aug 17 '14 at 09:55
  • 1
    Wait, if your problem is with other applications, please confirm this. If your problem is with "partially loaded" application something is going wrong with your environment. – AlexR Aug 17 '14 at 09:57
  • It's not only other webapps. I did the following experiment, you can try it, just to make my point clear: I created a TestService, that is picked up by spring auto scan. I added a @PostConstruct method that throws NPE. That service is failing, but the entire webapp loads (i.e. server replies to requests as usual). – Elad Tabak Jan 29 '15 at 14:49
  • Appears to be a duplicate of https://stackoverflow.com/questions/37472693/stop-the-spring-web-application-if-a-bean-initialization-fails – jpierson Apr 06 '19 at 13:12
  • Another possible duplicate https://stackoverflow.com/questions/38335529/tomcat-stop-after-failed-deployment – jpierson Apr 06 '19 at 13:13
  • I would recommend changing the title of this question to indicate that the question is about doing to fail-fast shutdown only during development. This nuance sets this question apart from some of the others on SO. – jpierson Apr 06 '19 at 13:20
  • I would recommend doing the same on production to avoid a partially functioning server. – Elad Tabak Apr 08 '19 at 07:26

1 Answers1

4

So eventually the solution I found is: Create a class that implements ServletContextListener, call it ApplicationLoaderListener.

Set this class in web.xml:

<listener>
    <listener-class>com.my.package.ApplicationLoaderListener</listener-class>
</listener>

Add a private member to it:

private final ServletContextListener loader = new ContextLoaderListener();

This class must implement the two interface methods, which the relevant one is contextInizialized:

@Override
public void contextInitialized(ServletContextEvent sce) {
    try {
        loader.contextInitialized(sce);
    } catch (BeanCreationException e) {
        handle(e);
    }
}

And the implementation of handle():

private void handle(BeanCreationException e) {
    log.error("=============== FATAL =============== - failed to create bean: ", e);
    System.exit(1);
}

And to make the code complete, the second method:

@Override
public void contextDestroyed(ServletContextEvent sce) {
    loader.contextDestroyed(sce);
}
Elad Tabak
  • 2,317
  • 4
  • 23
  • 33
  • A decorator for ContextLoaderListener :-/ I wish there were a better way – f.khantsis May 08 '16 at 19:21
  • It looks like when exception occurs contextDestroyed() is called but it doesn't make an exit(). So maybe we should call exit inside contextDestroyed() instead of handle() – Sergey Ponomarev Jul 05 '18 at 10:59
  • See https://stackoverflow.com/questions/38335529/tomcat-stop-after-failed-deployment with solution https://github.com/ascheman/tomcat-lifecyclelistener – Sergey Ponomarev Jul 05 '18 at 11:37
  • Another solution here: https://stackoverflow.com/a/49250137/170239 Is there a benefit to one solution over the other? – chrismacp Apr 26 '19 at 13:50