3 ms·
If you have a top level catch, then you lose the local context of the error (local variables, parameters, stack trace). I mean seriously, this is a solved probl
by js8 8y ago
If you have a top level catch, then you lose the local context of the error (local variables, parameters, stack trace). I mean seriously, this is a solved problem on z/OS (the ABEND condition bypasses normal stack, so to speak), it has been solved for over 50 years. I don't see why JVM couldn't do the same thing - is it a technical problem? It seems like a purely cultural problem to me.
- deepsun 8y agoMaybe because in Java it's usually considered a very bad practice to halt your program. All the web containers that run your code will catch any error, to prevent bringing down the whole web service if only a small piece of it fails (for example, cannot serve one URL, but can others). So instead, in Java, it's your responsibility to catch and correctly handle all the exceptions. Also, variables in the last function (where exception was raised from) are unlikely to give me understanding of the bug, because it's usually thrown somewhere deep in others code, and also I'm more interested in _why_ it happened, not just _what_ happened. We could dump all the variables in the stack trace, but I'm not sure I would like to read the whole dump of every variable in stack trace, that's just too much. I'd better write my code with proper logging, so I would be able to read the logs in order to understand not only _what_ happened, but _why_ it happened. With good logs you rarely even need to debug anything, I'd say 95% of the time it's pretty clear where to fix.
- js8 8y agoAgain, on z/OS, this is a solved problem. If the application runs inside an "application server", for instance CICS, you can still get the dump and the CICS can continue or even restart your app (or it can be restarted through other things). You can get the dump of the process even if just one thread will fail. I know from experience on z/OS how useful full dump can be, and I sorely miss it in Java. You wouldn't have to read the full dump yourself - a good postmortem debugger can do that work for you - displaying stack trace, locals, etc. Good logs can certainly save you.. if you have them, and you happen to log exactly what you need. But it's much easier to look at the memory and see what went wrong. (Personally, I think logs are great on the boundary, to describe inputs and outputs.) I also think that the exceptions are kind of wrong approach (compared to z/OS ABEND conditions), and it's not entirely true that failing loudly is a bad practice, but that's for another discussion.
- jillesvangurp 8y agoIndeed a cultural thing in the sense that a JVM crashing is rare and exceptions are both common and non-fatal. In short, that's what logging is for and there are some awesome options for that in Java. We log all exceptions with stacktrace + full MDC (mapped diagnostic context) to a central logging cluster. Also, we start alerting if that happens. Most application servers will have a top level catch and a way of logging/handling exceptions (e.g. sending a 500 response for unhandled exceptions). The JVM crashing usually means you are hitting a jvm bug; it's not supposed to do that. It's been a while since I had that going on. Even out of memory exceptions tend to happen in a somewhat orderly fashion. It will print some message probably. Setting -XX:+HeapDumpOnOutOfMemoryError does what you want here: dumping the memory. Of course the use of that on an ephemeral disk in e.g. Docker is kind of limited. These heap dumps are super detailed though and you can dig through them using special tools. A common issue with docker is not setting limits correctly and then docker killing your process instead of it exiting the normal way. You can dump a stack trace of all threads to std out by sending kill -QUIT to the process (does not kill the process). Great for debugging deadlocks.