On Tue, 20 Sep 2022 06:00:14 GMT, Alan Bateman <al...@openjdk.org> wrote:
>> src/java.base/share/classes/java/io/FilterOutputStream.java line 195: >> >>> 193: // evaluate possible precedence of flushException >>> over closeException >>> 194: if ((flushException instanceof ThreadDeath) && >>> 195: !(closeException instanceof ThreadDeath)) { >> >> If the ThreadDeath originates from the debugger then this is now a change in >> behaviour. > >> Good to see this finally become non-functional but as long as the >> debugger/JVMTI can trigger throwing an async ThreadDeath then I have to >> question the potential change in behaviour introduced by removing all the >> `catch (ThreadDeath td)` logic in various places. > > I've gone through this a few times too and concluded it would be better to > remove these untestable code paths. The debugger scenario is more like what > used to be Thread.stop(Throwable). It can be used to throw any exception or > error, e.g. ask the debugger to throw IllegalArgumentException or > SQLException when I'm at this breakpoint so I can see how the code behaves. > Yes, the user could ask the debugger to throw java.lang.ThreadDeath when > prompted but it's not really interesting now because code won't get this > error outside of a debugger. We could leave the special handing but we have > no way to test is and we'll need to the remove the special handling when TD > is removed. As a general point, the special casing of TD is a bit > inconsistent and more likely to be seen in older code rather newer code. A > static analysis of 24M classes found very few usages in 3rd party libraries. I agree with Alan on this. First, use and handling of `ThreadDeath` is quite rare; see my [analysis](https://bugs.openjdk.org/browse/JDK-8289610?focusedCommentId=14523723&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14523723) of the corpus search results in the bug report. Second, while this does change the behavior in the debugger case, I'm hard-pressed to see how anybody is _relying_ on such behavior. And maybe somebody somewhere is indeed relying on this behavior, but it doesn't seem to me this behavior is guaranteed by any specifications. A more likely way that programs could observe changes in `ThreadDeath` handling occurs when programs throw `ThreadDeath` explicitly, that is, not using `Thread.stop`. This does seem to occur infrequently "in the wild" (we'll fix the jshell case). The point of throwing `ThreadDeath` explicitly is to take advantage of special-case handling of `ThreadDeath` that might occur higher in the call stack. Such special-casing was at one time an accepted exception handing idiom, but it's essentially disused. I don't think the JDK needs to continue to support this old idiom. ------------- PR: https://git.openjdk.org/jdk/pull/10230