On Tue, 20 Sep 2022 06:00:14 GMT, Alan Bateman <[email protected]> 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