Constantine Lee
Constantine Lee

Reputation: 157

Does an unhandled runtime exception crash the whole server?

Will an unhandled runtime exception stop the whole server (i.e. Spring Boot application) or just the specific HTTP request ?

It is true that an unhandled runtime exception will instantly shut down normal Java application, right ?

Upvotes: 7

Views: 3646

Answers (3)

Stephen C
Stephen C

Reputation: 718708

Will an unhandled runtime exception stop the whole server (i.e. Spring Boot application) or just the specific HTTP request ?

Just the current HTTP request ... assuming that the exception is thrown by the request thread. (If it is thrown by a child thread, it won't even terminate the HTTP request.)


It is true that an unhandled runtime exception will instantly shut down normal Java application, right?

Actually, not right.

An uncaught exception causes the thread on which it was thrown to terminate. In a simple Java application where there is only one (non-daemon) "main" thread, and an uncaught exception occurs on that thread, the JVM then exit because the last non-daemon thread has terminated.

But if there are other threads ... the uncaught exception doesn't stop the JVM.

To illustrate, run this program:

public class Test {
    public static void main(String[] args) {
        new Thread(() -> {
            try {
                Thread.sleep(10000);
            } catch (Exception e) {
                System.err.println("Caught " + e);
            }
        }).start();
        throw new RuntimeException("Goodbye cruel world");
    }
}

When you run this, you will observe that there is a 10 second delay between the stacktrace printing (from the uncaught exception in main) and the program actually ending. The JVM is waiting for the child thread to terminate.


This could also indirectly answer your main question ... except:

  • We don't know for sure if the request threads are daemon threads or not.
  • We don't know for sure that the request threads are not actually catching / handling the exceptions thrown by your request processing code.

Suffice it to say that a framework will typically do something sensible depending one what the thrown exception is. For example, a framework might handle Error exceptions on a worker thread by attempting a shutdown ... on the basis that the error may have put the JVM into a potentially unsafe / non-recoverable state.

Upvotes: 8

zysaaa
zysaaa

Reputation: 1867

Will an unhandled runtime exception stop the whole server (i.e. Spring Boot application) or just the specific HTTP request ?

There is usually a thread pool in web server to handle all requests(e.g tomcat). Uncaught exceptions that occur in your controller will eventually be caught somewhere, so it will not cause the worker thread in the thread pool to be killed.

Tomcat#AbstractEndpoint#processSocket:

Executor executor = getExecutor();
if (dispatch && executor != null) {
    // handle request in thread poll
    executor.execute(sc);
} 

I did a simple debug. Assuming that an unhandle exception occurred in your controller, then the exception was actually caught by FrameworkServlet#processRequest. After the capture, it will be wrapped into a NestedServletException and continue to be thrown to the upper layer. Eventually, it will be caught and printed in StandardWrapperValve#invoke.

Upvotes: 1

Anonymous
Anonymous

Reputation: 86193

Just the thread in question

An unhandled RuntimeException will kill the thread, not the application. Usually each HTTP request is handled by its own thread, so nothing else in the server should be affected. I don’t know how the server handles the dead thread. A wise move would probably be creating a new thread for upcoming requests.

Only when all threads (except so-called demon threads) are terminated, will your Spring Boot application stop. This in turn means that in an application that isn’t threaded — one that has everything running in the main thread — an uncaught exception (RuntimeException or some other type) will bring the whole program down.

In most applications it matters which thread is killed. Your application probably has more threads handling HTTP requests and can spawn new ones as needed. In this case a thread death will hardly be noticed except by the user having sent this HTTP request. Other threads are probably more vital to the functioning of the server, and such a thread being killed, while not stopping the server completely, will stop it from working properly. For a different example, if the event dispatching thread in a desktop application is killed by an exception, the application can no longer accept user input.

Try it out for yourself

It doesn’t take a lot to try it out. The following program spawns a thread that throws an unhandled exception.

public class DemoUnhandledException {

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> { throw new RuntimeException("Demo"); }).start();
        TimeUnit.MINUTES.sleep(1);
        System.out.println("A minute later the main thread is still alive and well");
    }

}

Let the program run for a full minute to get the full output, which is:

Exception in thread "Thread-0" java.lang.RuntimeException: Demo
  at ovv.so.exception.DemoUnhandledException.lambda$0(DemoUnhandledException.java:8)
  at java.base/java.lang.Thread.run(Thread.java:834)
A minute later the main thread is still alive and well

Link

How uncaught exceptions are handled in Java on Javamex

Upvotes: 4

Related Questions