United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 7148143 PropertyChangeSupport.addPropertyChangeListener can throw ClassCastException
7148143 : PropertyChangeSupport.addPropertyChangeListener can throw ClassCastException

Details
Type:
Bug
Submit Date:
2012-02-23
Status:
Resolved
Updated Date:
2012-03-27
Project Name:
JDK
Resolved Date:
2012-03-14
Component:
client-libs
OS:
windows_7
Sub-Component:
java.beans
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
8

Related Reports
Backport:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b05)
Java HotSpot(TM) Client VM (build 22.1-b02, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7600]

A DESCRIPTION OF THE PROBLEM :
Under Java7 there's a regression in PropertyChangeSupport.addPropertyChangeListener(String, PropertyChangeListener) whereby a ClassCastException is thrown when the specified listener extends EventListenerProxy<T> and T does not extend PropertyChangeListener.

It appears to be due to PropertyChangeSupport.PropertyChangeListenerMap wrongly assuming that all wrapped EventListenerProxy<?> listeners are EventListenerProxy<PropertyChangeListener>.  The unwrapping in PropertyChangeListenerMap.extract should be restricted to PropertyChangeListenerProxys.

REGRESSION.  Last worked in version 6u29

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Test case completing successfully.
ACTUAL -
The attached exception is thrown.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ClassCastException: Main$MyListener cannot be cast to java.beans.PropertyChangeListener
	at java.beans.PropertyChangeSupport.addPropertyChangeListener(PropertyChangeSupport.java:201)
	at Main.main(Main.java:36)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.EventListener;
import java.util.EventListenerProxy;

public class Main
{
	public static class MyListener implements EventListener
	{
	}
	
	public static class MyProxyListener extends EventListenerProxy<MyListener> implements PropertyChangeListener
	{
		public MyProxyListener(MyListener proxy)
		{
			super(proxy);
		}
		
		@Override
		public void propertyChange(PropertyChangeEvent event)
		{
		}
	}
	
	public static void main(String[] args)
	{
		MyListener listener = new MyListener();
		PropertyChangeListener proxyListener = new MyProxyListener(listener);
		PropertyChangeSupport support = new PropertyChangeSupport(new Main());
		
		// OK
		support.addPropertyChangeListener(proxyListener);
		
		// throws ClassCastException in Java7
		support.addPropertyChangeListener("foo", proxyListener);
	}
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Introduce EventListenerProxy2 as a copy of EventListenerProxy and extend that instead for added property change listeners, if possible.

                                    

Comments
EVALUATION

We should implement the extract method for specific classes only.
                                     
2012-02-29



Hardware and Software, Engineered to Work Together