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.
|