From fcb3a065304479c449bc1bcf0fde29f031cd5589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B0=D0=BD=D0=B4=D1=8A?= =?UTF-8?q?=D1=80=20=D0=9A=D1=83=D1=80=D1=82=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Tue, 23 Dec 2025 11:45:32 +0200 Subject: [PATCH] Stop dealing with ThreadDeath Java 20+ Thread.stop throws UnsupportedOperationException and thus ThreadDeath is not thrown by anything anymore. Stop dealing with it. https://inside.java/2022/11/09/quality-heads-up/ --- .../workbench/swt/IEventLoopAdvisor.java | 33 +++++++++---------- .../workbench/swt/PartRenderingEngine.java | 8 +---- .../eclipse/jface/operation/ModalContext.java | 20 ++--------- .../src/org/eclipse/jface/window/Window.java | 7 +--- .../ui/application/WorkbenchAdvisor.java | 4 +-- .../eclipse/ui/internal/ExceptionHandler.java | 10 ++---- .../workbench/PartRenderingEngineTests.java | 6 ---- 7 files changed, 24 insertions(+), 64 deletions(-) diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/IEventLoopAdvisor.java b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/IEventLoopAdvisor.java index 5c1d6577b9d..7f18033c0cf 100644 --- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/IEventLoopAdvisor.java +++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/IEventLoopAdvisor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2015 IBM Corporation and others. + * Copyright (c) 2011, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -39,27 +39,26 @@ public interface IEventLoopAdvisor { public void eventLoopIdle(Display display); /** - * Performs arbitrary actions when the event loop crashes (the code that - * handles a UI event throws an exception that is not caught). + * Performs arbitrary actions when the event loop crashes (the code that handles + * a UI event throws an exception that is not caught). *

- * This method is called when the code handling a UI event throws an - * exception. In a perfectly functioning application, this method would - * never be called. In practice, it comes into play when there are bugs in - * the code that trigger unchecked runtime exceptions. It is also activated - * when the system runs short of memory, etc. Fatal errors (ThreadDeath) are - * not passed on to this method, as there is nothing that could be done. + * This method is called when the code handling a UI event throws an exception. + * In a perfectly functioning application, this method would never be called. In + * practice, it comes into play when there are bugs in the code that trigger + * unchecked runtime exceptions. It is also activated when the system runs short + * of memory, etc. Fatal errors are not passed on to this method, as there is + * nothing that could be done. *

*

- * Clients must not call this method directly (although super calls are - * okay). The default implementation logs the problem so that it does not go - * unnoticed. Subclasses may override or extend this method. It is generally - * a bad idea to override with an empty method, and you should be especially - * careful when handling Errors. + * Clients must not call this method directly (although super calls are okay). + * The default implementation logs the problem so that it does not go unnoticed. + * Subclasses may override or extend this method. It is generally a bad idea to + * override with an empty method, and you should be especially careful when + * handling Errors. *

* - * @param exception - * the uncaught exception that was thrown inside the UI event - * loop + * @param exception the uncaught exception that was thrown inside the UI event + * loop */ public void eventLoopException(Throwable exception); } diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java index cfcd37e51d0..f69766adcf0 100644 --- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java +++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/internal/workbench/swt/PartRenderingEngine.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2019 IBM Corporation and others. + * Copyright (c) 2008, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1151,8 +1151,6 @@ public void eventLoopException(Throwable exception) { } advisor.eventLoopIdle(display); } - } catch (ThreadDeath th) { - throw th; } catch (Exception | Error err) { handle(err, advisor); } @@ -1166,10 +1164,6 @@ private void handle(Throwable ex, IEventLoopAdvisor advisor) { try { advisor.eventLoopException(ex); } catch (Throwable t) { - if (t instanceof ThreadDeath) { - throw (ThreadDeath) t; - } - // couldn't handle the exception, print to console t.printStackTrace(); } diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/operation/ModalContext.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/operation/ModalContext.java index 7a8e2fb5244..e790734796e 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/operation/ModalContext.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/operation/ModalContext.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -122,10 +122,6 @@ public void run() { if (runnable != null) { runnable.run(progressMonitor); } - } catch (ThreadDeath e) { - // Make sure to propagate ThreadDeath, or threads will never - // fully terminate. - throw e; } catch (InvocationTargetException | InterruptedException | RuntimeException | Error e) { throwable = e; } finally { @@ -170,12 +166,6 @@ public void block() { } exceptionCount = 0; } - // ThreadDeath is a normal error when the thread is dying. - // We must propagate it in order for it to properly - // terminate. - catch (ThreadDeath e) { - throw (e); - } // For all other exceptions, log the problem. catch (Throwable t) { if (t instanceof VirtualMachineError) { @@ -414,10 +404,6 @@ public static void run(IRunnableWithProgress operation, boolean fork, static Throwable invokeThreadListener(IThreadListener listener, Thread switchingThread) { try { listener.threadChange(switchingThread); - } catch (ThreadDeath e) { - // Make sure to propagate ThreadDeath, or threads will never - // fully terminate - throw e; } catch (RuntimeException | Error e) { return e; } @@ -438,9 +424,7 @@ private static void runInCurrentThread(IRunnableWithProgress runnable, IProgress InterruptedException interruptedException = new InterruptedException(e.getLocalizedMessage()); interruptedException.initCause(e); throw interruptedException; - } catch (InvocationTargetException | InterruptedException | ThreadDeath e) { - // Make sure to propagate ThreadDeath, or threads will never fully - // terminate. + } catch (InvocationTargetException | InterruptedException e) { throw e; } catch (RuntimeException | Error e) { throw new InvocationTargetException(e); diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/window/Window.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/window/Window.java index 0b9c5aa68d9..444b0c1dab5 100644 --- a/bundles/org.eclipse.jface/src/org/eclipse/jface/window/Window.java +++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/window/Window.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -129,11 +129,6 @@ public static interface IExceptionHandler { private static class DefaultExceptionHandler implements IExceptionHandler { @Override public void handleException(Throwable t) { - if (t instanceof ThreadDeath) { - // Don't catch ThreadDeath as this is a normal occurrence when - // the thread dies - throw (ThreadDeath) t; - } // Try to keep running. t.printStackTrace(); } diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/application/WorkbenchAdvisor.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/application/WorkbenchAdvisor.java index 441bc25deaf..294f3b727e3 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/application/WorkbenchAdvisor.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/application/WorkbenchAdvisor.java @@ -280,8 +280,8 @@ public void postShutdown() { * In a perfectly functioning application, this method would never be called. In * practice, it comes into play when there are bugs in the code that trigger * unchecked runtime exceptions. It is also activated when the system runs short - * of memory, etc. Fatal errors (ThreadDeath) are not passed on to this method, - * as there is nothing that could be done. + * of memory, etc. Fatal errors are not passed on to this method, as there is + * nothing that could be done. *

*

* Clients must not call this method directly (although super calls are okay). diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/ExceptionHandler.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/ExceptionHandler.java index 965d4a82284..703f7d6a189 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/ExceptionHandler.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/ExceptionHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -17,8 +17,7 @@ /** * This handler will pass along to the workbench advisor exceptions and errors - * thrown while running the event loop. However, the ThreadDeath - * error is simply thrown again, and is not passed along. + * thrown while running the event loop. */ public final class ExceptionHandler implements Window.IExceptionHandler { @@ -42,11 +41,6 @@ private ExceptionHandler() { @Override public void handleException(Throwable t) { try { - // Ignore ThreadDeath error as its normal to get this when thread dies - if (t instanceof ThreadDeath) { - throw (ThreadDeath) t; - } - // Check to avoid recursive errors exceptionCount++; if (exceptionCount > 2) { diff --git a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/workbench/PartRenderingEngineTests.java b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/workbench/PartRenderingEngineTests.java index 892e40a2c11..f22fb36b344 100644 --- a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/workbench/PartRenderingEngineTests.java +++ b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/workbench/PartRenderingEngineTests.java @@ -151,12 +151,6 @@ private void handle(Throwable ex, IEventLoopAdvisor advisor) { try { advisor.eventLoopException(ex); } catch (Throwable t) { - // The type ThreadDeath has been deprecated since version 20 - // and marked for removal - if ("ThreadDeath".equals(t.getClass().getSimpleName())) { - // don't catch ThreadDeath by accident - throw t; - } // couldn't handle the exception, print to console t.printStackTrace(); } finally {