Uploaded image for project: 'NetBeans'
  1. NetBeans
  2. NETBEANS-406

addPropertyChangeListener w/o matching removePropertyChangeListener

    XMLWordPrintableJSON

Details

    Description

      The following warning appears in the IDE log every now and then in 8.2 and 9.0 beta:

       

      WARNING [org.openide.util.WeakListenerImpl]: Can't remove java.beans.PropertyChangeListener using method org.netbeans.modules.editor.NbEditorDocument.removePropertyChangeListener from org.netbeans.modules.editor.NbEditorDocument@299b063c, mimeType='text/x-editor-search', kitClass=null, length=9, version=15, file=null

       

      The warning above can be reproduced by opening a Java editor, closing all editors, and then invoking a GC with by double-clicking the memory meter in the "Performance" toolbar item. 

      This bug was previously discussed in Bugzilla at https://netbeans.org/bugzilla/show_bug.cgi?id=196323 . Not sure what priority to put for this bug; it's a memory leak, but I'm not sure how big of an impact it has.

      Analysis

      Storing a stacktrace in WeakListenerImpl.ListenerReference on creation and then printing it on the failed removal shows the place where the problematic listener is added:

      java.lang.Exception
       at org.openide.util.WeakListenerImpl$ListenerReference.<init>(WeakListenerImpl.java:554)
       at org.openide.util.WeakListenerImpl.<init>(WeakListenerImpl.java:109)
       at org.openide.util.WeakListenerImpl.<init>(WeakListenerImpl.java:99)
       at org.openide.util.WeakListenerImpl$PropertyChange.<init>(WeakListenerImpl.java:187)
       at org.openide.util.WeakListeners.propertyChange(WeakListeners.java:282)
       at org.netbeans.modules.editor.lib2.view.DocumentViewOp.checkSettingsInfo(DocumentViewOp.java:937)
       at org.netbeans.modules.editor.lib2.view.DocumentViewOp.checkViewsInited(DocumentViewOp.java:622)
       at org.netbeans.modules.editor.lib2.view.DocumentView.getPreferredSpan(DocumentView.java:251)
       at javax.swing.plaf.basic.BasicTextUI$RootView.getPreferredSpan(BasicTextUI.java:1353)
       at javax.swing.plaf.basic.BasicTextUI.getPreferredSize(BasicTextUI.java:919)
       at javax.swing.JComponent.getPreferredSize(JComponent.java:1662)
       at javax.swing.JEditorPane.getPreferredSize(JEditorPane.java:1333)
       at org.netbeans.modules.editor.NbEditorUI$LayeredEditorPane.getPreferredSize(NbEditorUI.java:475)

      The problem is on this line of DocumentViewOp:

      o.n.modules.editor.lib2.view.DocumentUtilities.addPropertyChangeListener(doc, WeakListeners.propertyChange(this, doc));

      The DocumentUtilities.addPropertyChangeListener is a special API for allowing property change listeners to be attached to BaseDocument instances (see Bugzilla https://netbeans.org/bugzilla/show_bug.cgi?id=181073 ). Since it doesn't actually add addPropertyChangeListener/removePropertyChangeListener methods to BaseDocument, it doesn't work with WeakListeners.

      As far as I can see, the only place that actually uses DocumentUtilities.addPropertyChangeListener is the single line i DocumentViewOp above.

      I would propose adding a removedPropertyChangeListener method to BaseDocument that delegates to DocumentUtilities.removePropertyChangeListener (or performs the equivalent logic itself). This way the WeakListener will find the method it expects when the listener is due to be removed, and the property change events will still have the Document instance as the event source instead of the delegate PropertyChangeSupport, as is probably desired.

      An alternative is to make WeakListeners aware of the special setup wrt. property change listeners on BaseDocument instances. But that seems like an abstraction violation.

      Attachments

        Activity

          People

            matthiasblaesing Matthias Bläsing
            ebakke Eirik Bakke
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 2h 40m
                2h 40m