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

Reply via email to