Bug 178815 - [Preferences] IllegalStateException when unregistering listener
diff --git a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/preferences/legacy/PreferenceForwarder.java b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/preferences/legacy/PreferenceForwarder.java
index d9a9bad..c065942 100644
--- a/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/preferences/legacy/PreferenceForwarder.java
+++ b/bundles/org.eclipse.core.runtime/src/org/eclipse/core/internal/preferences/legacy/PreferenceForwarder.java
@@ -73,14 +73,8 @@
* @see org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener#removed(org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent)
*/
public synchronized void removed(IEclipsePreferences.NodeChangeEvent event) {
- if (listeners.size() > 0 && pluginID.equals(event.getChild().name())) {
- try {
- EclipsePreferences prefs = (EclipsePreferences) event.getChild();
- prefs.removePreferenceChangeListener(this);
- } catch (ClassCastException e) {
- throw new RuntimeException("Plug-in preferences must be instances of EclipsePreferences: " + e.getMessage()); //$NON-NLS-1$
- }
- }
+ // Do nothing. We can't remove ourselves from the node's list of preference change
+ // listeners because the node has already been removed.
}
/**
diff --git a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/PreferenceForwarderTest.java b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/PreferenceForwarderTest.java
index cdd857e..1f384f7 100644
--- a/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/PreferenceForwarderTest.java
+++ b/tests/org.eclipse.core.tests.runtime/src/org/eclipse/core/tests/runtime/PreferenceForwarderTest.java
@@ -15,7 +15,13 @@
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.preferences.legacy.PreferenceForwarder;
-import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.internal.runtime.RuntimeLog;
+import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.osgi.service.prefs.BackingStoreException;
/**
* Test suite for API class org.eclipse.core.runtime.Preferences
@@ -65,9 +71,9 @@
// all test methods are named "test..."
return new TestSuite(PreferenceForwarderTest.class);
- // TestSuite suite = new TestSuite();
- // suite.addTest(new PreferenceForwarderTest("testDefaultPropertyNames"));
- // return suite;
+// TestSuite suite = new TestSuite();
+// suite.addTest(new PreferenceForwarderTest("testListenerOnRemove"));
+// return suite;
}
/*
@@ -817,4 +823,44 @@
int b = 3;
}
*/
+
+ /*
+ * Regression test for bug 178815.
+ */
+ public void testListenerOnRemove() {
+ // create a new log listener that will fail if anything is written
+ ILogListener logListener = new ILogListener() {
+ public void logging(IStatus status, String plugin) {
+ CoreException ex = new CoreException(status);
+ fail("0.99", ex);
+ }
+ };
+
+ // set a preference value to get everything initialized
+ String id = getUniqueString();
+ Preferences ps = new PreferenceForwarder(id);
+ ps.setValue("key", "value");
+
+ // add a property change listener which will cause one to be
+ // added at the preference node level
+ IPropertyChangeListener listener = new Preferences.IPropertyChangeListener(){
+ public void propertyChange(PropertyChangeEvent event) {
+ }
+ };
+ ps.addPropertyChangeListener(listener);
+ ps.setValue("key2", "value2");
+ IEclipsePreferences node = new InstanceScope().getNode(id);
+
+ // add our log listener and remove the node. nothing should be logged.
+ RuntimeLog.addLogListener(logListener);
+ try {
+ node.removeNode();
+ } catch (BackingStoreException e) {
+ fail("4.99", e);
+ } catch (IllegalStateException e) {
+ fail("5.00", e);
+ } finally {
+ RuntimeLog.removeLogListener(logListener);
+ }
+ }
}