This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 196323

Summary: addPropertyChangeListener w/o matching removePropertyChangeListener
Product: editor Reporter: Jesse Glick <jglick>
Component: -- Other --Assignee: ebakke
Status: REOPENED ---    
Severity: normal    
Priority: P4    
Version: 7.0   
Hardware: PC   
OS: Linux   
Issue Type: DEFECT Exception Reporter:
Attachments: Log file from NetBeans 8.1 showing the "Can't remove java.beans.PropertyChangeListener" warning

Description Jesse Glick 2011-03-04 18:38:20 UTC
Frequently printed in log:

WARNING [org.openide.util.WeakListenerImpl]: Can't remove java.beans.PropertyChangeListener using method removePropertyChangeListener from org.netbeans.modules.editor.NbEditorDocument@e21a17, mimeType='text/x-java', kitClass=null, length=94, version=1,[MasterFileObject[/tmp/test192735/src/it/java/p/,valid=true]]
Comment 1 Milutin Kristofic 2013-01-31 17:59:33 UTC
Can you provide reproducible steps? I don't see it in 7.3 logs.
Comment 2 Jesse Glick 2013-01-31 21:51:18 UTC
I did not have any reproducible steps two years ago so I certainly do not now. Just something I noticed in my log file.

Unclear to me how the listener got added since there is no add/removePCL method in this class or its superclasses. Probably someone mistakenly wrote

PropertyChangeListener pcl = …;
NbEditorDocument doc = …;
SomeOtherThing thing = …;
thing.addPropertyChangeListener(WeakListeners.propertyChange(pcl, doc));

Probably a Jackpot hint could be written to detect mismatches between the claimed and actual event source, i.e. something like (unsure of syntax):

$actual.addPropertyChangeListener(WeakListeners.propertyChange($l, $claimed)) :: $actual != $claimed => <warning>;

and of course also including other weak listener factories.
Comment 3 Milutin Kristofic 2013-02-04 15:16:05 UTC
Thank you for reply. You are right, that can be one reason that it happens sometimes. If somebody reopen with recent log file, I will do some investigation.
Comment 4 ebakke 2016-03-10 00:38:06 UTC
Created attachment 158793 [details]
Log file from NetBeans 8.1 showing the "Can't remove java.beans.PropertyChangeListener" warning

Uploading a recent NetBeans 8.1 log file showing the following warning:

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@48496435, mimeType='text/x-java', kitClass=null, length=6027, version=1,[AbstractFileObject@58324cb9[javax/swing/text/]]

I also get this message in my NetBeans Platform application--it started when I upgraded it from 8.0 to 8.1.

Reopening the bug per Milutin's previous comment. (Or happy to create a new bug.)
Comment 5 ebakke 2017-11-08 02:49:09 UTC
This bug now seems easy enough to reproduce; I can produce the message 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.

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:

	at org.openide.util.WeakListenerImpl$ListenerReference.<init>(
	at org.openide.util.WeakListenerImpl.<init>(
	at org.openide.util.WeakListenerImpl.<init>(
	at org.openide.util.WeakListenerImpl$PropertyChange.<init>(
	at org.openide.util.WeakListeners.propertyChange(
	at org.netbeans.modules.editor.lib2.view.DocumentViewOp.checkSettingsInfo(
	at org.netbeans.modules.editor.lib2.view.DocumentViewOp.checkViewsInited(
	at org.netbeans.modules.editor.lib2.view.DocumentView.getPreferredSpan(
	at javax.swing.plaf.basic.BasicTextUI$RootView.getPreferredSpan(
	at javax.swing.plaf.basic.BasicTextUI.getPreferredSize(
	at javax.swing.JComponent.getPreferredSize(
	at javax.swing.JEditorPane.getPreferredSize(
	at org.netbeans.modules.editor.NbEditorUI$LayeredEditorPane.getPreferredSize(

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 #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.
Comment 6 ebakke 2018-02-18 03:42:11 UTC
Added this bug to the new Apache JIRA here: