What is the rationale behind the policy of failed signal handlers in Java?

Much has been written about the wisdom of exceptions in general and the use of checked and excluded exceptions in Java in particular, but I'm interested in protecting the decision to make thread termination the default policy instead of terminating the application as it is in C + +. This choice seems extremely dangerous to me: some condition that the programmer did not plan to randomly cause some part of the program to die after registering the stack trace, but the rest of the soldiers of the program are determined, what could go wrong? My intuition and experience suggests that a lot can go wrong here, and the default policy is something that should be chosen on purpose by someone with a specific reason for choosing it, so what's up with this strategy. which is such a seemingly big drawback? Am I overestimating risk?

EDIT: Based on the answers so far, I feel that I need to focus more on my description of the dangers I perceive; I'm talking about the case of an application that uses multiple threads (such as a thread pool) to update shared state. I admit that this policy is not a problem for single threaded applications.

EDIT2: You can see that among those who maintain the language understand these risks from explaining why the Thread.stop () method was deprecated (here: http://docs.oracle.com/javase/7/docs/ technotes / guides / concurrency / threadPrimitiveDeprecation.html ). The exact same issues apply when a thread dies unexpectedly due to uncaught exceptions. They had to design the JVM so that all monitors would automatically unlock when a thread dies, which seems like a poor implementation choice; with a thread write while blocked by the monitor should indicate that the entire program should die, because the alternative will almost certainly be an internal inconsistency in some general state.

+3


source to share


3 answers


@BD, Not sure what your story is talking about because you didn't explain it here. But here's what I experienced as a developer:

  • It is generally a bad idea to crash an application if one of its components fails (temporarily or permanently) due to any reason, such as reloading the database or replacing a file. for example, if I introduced a new type of trade to the system and there was some problem, it shouldn't shut down my application.

  • Apps like webservers / apps should be able to keep running and responding to user requests even if any of its deployment throws any strange exception / s.



Depending on your concern about exceptions, generally all applications have a health monitoring system that monitors their health, such as CPU / Disk / RAM usage, errors in logs, etc. and accordingly warns of fire.

I hope this should resolve your confusion.

+1


source


After discussing this issue with a colleague and also analyzing the responses received, I made an assumption here and would like some feedback.

I suspect the decision to make this the default behavior has its roots in the philosophy that determined the early development of the language as well as its early environment.

As part of the original philosophy, programmers / designers expected to use checked exceptions, and the language enforces that checked exceptions that might be thrown by a method call (i.e., were declared in the method definition) should be handled in, or declared "officially" transfer responsibility for higher level subscribers. Common practice has moved away sharply from using checked exceptions, not to mention one of the most common exceptions in practice, NullPointerException, is unchecked. As a result of this, programmers must now assume that any method call can throw an unchecked exception, and the consequence is that any code that updates shared data in a parallel context ismust implement the transaction semantics for these updates to be completely correct.My experience is that most developers don't understand this, even if they understand the basics of multi-threaded development, such as avoiding deadlocks when managing critical sections with synchronization. The default behavior of an excluded handler exacerbates the problem by masking its effects: in C ++ it doesn't matter if an uncaught exception will result in a corrupted shared state, because the program is dead anyway, but in Java the program will continue to limp along the best way possible despite that it will likely no longer work correctly.avoiding deadlocks when managing critical sections with synchronization. The default behavior of an excluded handler exacerbates the problem by masking its effects: in C ++ it doesn't matter if an uncaught exception will result in a corrupted shared state, because the program is dead anyway, but in Java the program will continue to limp along the best way possible despite that it will most likely no longer work correctly.avoiding deadlocks when managing critical sections with synchronization. The default behavior of an excluded handler exacerbates the problem by masking its effects: in C ++ it doesn't matter if an uncaught exception will result in a corrupted shared state, because the program is dead anyway, but in Java the program will continue to limp along the best way possible despite that it will likely no longer work correctly.even though it will most likely no longer work correctly.even though it will most likely no longer work correctly.



The environmental factor is that single-threaded programs are probably the norm when the language was first developed, so the default behavior is masked as correct. The emergence of multi-core architectures and the increased use of thread pools exposes the threat more broadly, and commonly used approaches such as using immutable objects may go as far as to fix this problem (hint for some: ConcurrentMap is probably not as secure as you think , what is it). My experience so far is that people who deny this risk are not paranoid enough about the actual security requirements of their code, but I would like you to be acquitted.

I suspect that changing the exception handlers to terminate the program should be a standard procedure required by most development organizations; at least this should be done for thread pools, which are known to update the overall state based on incoming inputs.

+1


source


Regular (no GUI, no container) applications break out of uncaught exceptions - the default behavior is fine - just as you wanted.

A GUI based application, it would be useful to show the error message and handle the error more efficiently - for example, we could submit a defect report with more information.

The behavior is completely mutable by providing a thread-specific exception handler that can trigger the application's exit.

Here are some helpful notes

0


source







All Articles