diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/statushandlers/StatusManager.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/statushandlers/StatusManager.java index ce14d1684a2..b83c036524f 100644 --- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/statushandlers/StatusManager.java +++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/statushandlers/StatusManager.java @@ -15,8 +15,9 @@ package org.eclipse.ui.statushandlers; -import java.util.List; -import java.util.Vector; +import java.util.Collections; +import java.util.Set; +import java.util.WeakHashMap; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.ILogListener; import org.eclipse.core.runtime.IStatus; @@ -116,7 +117,9 @@ public class StatusManager { private volatile AbstractStatusHandler statusHandler; - private final List loggedStatuses = new Vector<>(); + // Weakly held so that a status which never reaches the log listener cannot accumulate. + private final Set loggedStatuses = Collections + .newSetFromMap(Collections.synchronizedMap(new WeakHashMap())); private final ListenerList listeners = new ListenerList<>(); diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusHandlingTestSuite.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusHandlingTestSuite.java index bd29e7a6a5a..e283865322e 100644 --- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusHandlingTestSuite.java +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusHandlingTestSuite.java @@ -29,6 +29,7 @@ SupportTrayTest.class, WorkbenchStatusDialogManagerImplTest.class, WizardsStatusHandlingTestCase.class, + StatusManagerTest.class, }) public class StatusHandlingTestSuite { // diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusManagerTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusManagerTest.java new file mode 100644 index 00000000000..6666abf81e1 --- /dev/null +++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/statushandlers/StatusManagerTest.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2026 vogella GmbH and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Lars Vogel - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ui.tests.statushandlers; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.ui.statushandlers.StatusManager; +import org.eclipse.ui.tests.leaks.LeakTests; +import org.junit.jupiter.api.Test; + +/** + * Tests that the {@link StatusManager} singleton does not retain the statuses it + * is told about. + */ +public class StatusManagerTest { + + /** + * The entry is only dropped again once the very same instance comes back + * through the log listener, which does not happen for every caller. + */ + @Test + public void testStatusNeverReachingTheLogListenerIsNotRetained() throws Exception { + ReferenceQueue queue = new ReferenceQueue<>(); + IStatus status = new Status(IStatus.ERROR, "org.eclipse.ui.tests", "never logged"); //$NON-NLS-1$ //$NON-NLS-2$ + WeakReference ref = new WeakReference<>(status, queue); + + StatusManager.getManager().addLoggedStatus(status); + status = null; // drop the only strong reference + + LeakTests.checkRef(queue, ref); + } +}