I used to think that it's not, but yesterday I had to do it. It's an application that uses Akka (an actor system implementation for the JVM) to process asynchronous jobs. One of the actors performs some PDF manipulation, and because the library is buggy, it dies with a StackOverflowError
every now and then.
The second aspect is that Akka is configured to shutdown its whole actor system if any JVM fatal error (e.g. StackOverflowError) is caught.
The third aspect is that this actor system is embedded inside a web app (for WTF-ish, legacy, reasons), so when the actor system is shut down, the web app is not. The net effect is that on a StackOverflowError
our job processing application becomes just an empty web app.
As a quick fix I had to catch the StackOverflowError
being thrown, so that the thread pool of the actor system isn't torn down. This lead me to think that maybe it's sometimes okay to catch such errors especially in contexts like this? When there's a thread pool processing arbitrary tasks? Unlike an OutOfMemoryError
I can't imagine how a StackOverflowError
can leave an application in an inconsistent state. The stack is cleared after such an error, so computation can go on normally. But maybe I'm missing something important.
Also, let it be noted that I'm all for fixing the error in the first place (as a matter of fact I have already fixed an SOE in this same app a few days ago), but I really don't know when this kind of situation might arise.
Why would it be better to restart the JVM process instead of catching the StackOverflowError
, mark that job as failed, and continue with my business?
Is there any compelling reason to never catch SOEs? Except "best practices", which is a vague term that tells me nothing.
StackOverflowException
s are usually due to a non-terminating chain of method calls - increasing the stack space would then increase the memory cost of a new thread for no benefit.:-)