#151415 - ignore exception from removePreferenceChangeListener and removeNodeChangeListener thrown when node has already been removed.
authorJiri Skrivanek <jskrivanek@netbeans.org>
Fri, 06 Mar 2009 08:56:57 +0100
changeset 51646367040c893
parent 515 6cfde7f2f826
child 517 d6a8e38723c8
child 518 39a4edbcd55b
child 899 cd3dd45b4c0f
#151415 - ignore exception from removePreferenceChangeListener and removeNodeChangeListener thrown when node has already been removed.
openide.util/src/org/openide/util/WeakListenerImpl.java
openide.util/test/unit/src/org/openide/util/WeakListenersTest.java
     1.1 --- a/openide.util/src/org/openide/util/WeakListenerImpl.java	Mon Feb 16 23:34:16 2009 +0300
     1.2 +++ b/openide.util/src/org/openide/util/WeakListenerImpl.java	Fri Mar 06 08:56:57 2009 +0100
     1.3 @@ -584,13 +584,16 @@
     1.4              try {
     1.5                  remove.invoke(src, params);
     1.6              } catch (Exception ex) { // from invoke(), should not happen
     1.7 -                String errMessage = "Problem encountered while calling " + methodClass + "." + methodName + "(...) on " + src; // NOI18N
     1.8 -                LOG.warning( errMessage );
     1.9 -                //detailed logging needed in some cases
    1.10 -                boolean showErrMessage = ex instanceof InvocationTargetException
    1.11 -                        || "object is not an instance of declaring class".equals(ex.getMessage());
    1.12 +                // #151415 - ignore exception from AbstractPreferences if node has been removed
    1.13 +                if (!"removePreferenceChangeListener".equals(methodName) && !"removeNodeChangeListener".equals(methodName)) {  //NOI18N
    1.14 +                    String errMessage = "Problem encountered while calling " + methodClass + "." + methodName + "(...) on " + src; // NOI18N
    1.15 +                    LOG.warning( errMessage );
    1.16 +                    //detailed logging needed in some cases
    1.17 +                    boolean showErrMessage = ex instanceof InvocationTargetException
    1.18 +                            || "object is not an instance of declaring class".equals(ex.getMessage());
    1.19  
    1.20 -                LOG.log(Level.WARNING, showErrMessage ? errMessage : null, ex);
    1.21 +                    LOG.log(Level.WARNING, showErrMessage ? errMessage : null, ex);
    1.22 +                }
    1.23              }
    1.24          }
    1.25  
     2.1 --- a/openide.util/test/unit/src/org/openide/util/WeakListenersTest.java	Mon Feb 16 23:34:16 2009 +0300
     2.2 +++ b/openide.util/test/unit/src/org/openide/util/WeakListenersTest.java	Fri Mar 06 08:56:57 2009 +0100
     2.3 @@ -47,8 +47,16 @@
     2.4  import java.util.ArrayList;
     2.5  import java.util.Arrays;
     2.6  import java.util.List;
     2.7 +import java.util.concurrent.atomic.AtomicBoolean;
     2.8 +import java.util.logging.Handler;
     2.9  import java.util.logging.Level;
    2.10 +import java.util.logging.LogRecord;
    2.11  import java.util.logging.Logger;
    2.12 +import java.util.prefs.NodeChangeEvent;
    2.13 +import java.util.prefs.NodeChangeListener;
    2.14 +import java.util.prefs.PreferenceChangeEvent;
    2.15 +import java.util.prefs.PreferenceChangeListener;
    2.16 +import java.util.prefs.Preferences;
    2.17  import javax.swing.event.ChangeEvent;
    2.18  import javax.swing.event.ChangeListener;
    2.19  import org.netbeans.junit.NbTestCase;
    2.20 @@ -71,7 +79,60 @@
    2.21      protected Level logLevel() {
    2.22          return Level.ALL;
    2.23      }
    2.24 -    
    2.25 +
    2.26 +    /** Tests that exception is not logged when WeakListenerImpl tries to
    2.27 +     * remove listener on already removed node (#151415). */
    2.28 +    public void testPreferenceChangeListener() throws Exception {
    2.29 +        PreferenceChangeListener pcl = new PreferenceChangeListener() {
    2.30 +
    2.31 +            public void preferenceChange(PreferenceChangeEvent evt) {
    2.32 +            }
    2.33 +        };
    2.34 +        NodeChangeListener ncl = new NodeChangeListener() {
    2.35 +
    2.36 +            public void childAdded(NodeChangeEvent evt) {
    2.37 +            }
    2.38 +
    2.39 +            public void childRemoved(NodeChangeEvent evt) {
    2.40 +            }
    2.41 +        };
    2.42 +        Preferences nbp = NbPreferences.forModule(WeakListeners.class);
    2.43 +        nbp.addPreferenceChangeListener(WeakListeners.create(PreferenceChangeListener.class, pcl, nbp));
    2.44 +        nbp.addNodeChangeListener(WeakListeners.create(NodeChangeListener.class, ncl, nbp));
    2.45 +        nbp.removeNode();
    2.46 +
    2.47 +        Logger logger = Logger.getLogger(WeakListenerImpl.class.getName());
    2.48 +        final AtomicBoolean nodeRemovedException = new AtomicBoolean(false);
    2.49 +        logger.addHandler(new Handler() {
    2.50 +
    2.51 +            @Override
    2.52 +            public void publish(LogRecord record) {
    2.53 +                Throwable t = record.getThrown();
    2.54 +                if (t != null) {
    2.55 +                    if (t.getCause() instanceof IllegalStateException && t.getCause().getMessage().equals("Node has been removed.")) {  //NOI18N
    2.56 +                        nodeRemovedException.set(true);
    2.57 +                    }
    2.58 +                }
    2.59 +            }
    2.60 +
    2.61 +            @Override
    2.62 +            public void flush() {
    2.63 +            }
    2.64 +
    2.65 +            @Override
    2.66 +            public void close() throws SecurityException {
    2.67 +            }
    2.68 +        });
    2.69 +        Reference<PreferenceChangeListener> ref = new WeakReference<PreferenceChangeListener>(pcl);
    2.70 +        pcl = null;
    2.71 +        assertGC("PreferenceChangeListener cannot be collected", ref);
    2.72 +        Reference<NodeChangeListener> ref1 = new WeakReference<NodeChangeListener>(ncl);
    2.73 +        ncl = null;
    2.74 +        assertGC("NodeChangeListener cannot be collected", ref1);
    2.75 +        Thread.sleep(2000);
    2.76 +        assertFalse("The \"Node has been removed\" exception should not be thrown from WeakListenerImpl.", nodeRemovedException.get());
    2.77 +    }
    2.78 +
    2.79      public void testOneCanCallHashCodeOrOnWeakListener () {
    2.80          Listener l = new Listener ();
    2.81          Object weak = WeakListeners.create (PropertyChangeListener.class, l, null);