JDK-4937062 : REGRESSION: beancontext.BeanContextChildSupport.add/remove PCL/VCL: unclear doc
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.beans
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_2.6
  • CPU: sparc
  • Submitted: 2003-10-14
  • Updated: 2017-05-16
  • Resolved: 2004-02-28
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b41Fixed
Related Reports
Relates :  
Description

Name: sdR10048			Date: 10/14/2003


Filed By      : SPB JCK team (###@###.###)
JDK           : java full version "1.5.0-beta-b23"
JCK           : 1.5
Platform[s]   : Solaris
switch/Mode   : 
JCK test owner : http://javaweb.eng/jct/sqe/JCK-tck/usr/owners.jto
Failing Test [s] : 
api/java_beans/beancontext/BeanContextChildSupport/index.html#add [BeanContextChildSupport0003] 


Specification excerpt:
======================
--------- J2SE API spec v.1.5 ---------
...
public void addPropertyChangeListener(String name,
                                      PropertyChangeListener pcl)
Adds a property change listener. 

Specified by:
addPropertyChangeListener in interface BeanContextChild
Parameters:
name - The name of the property to listen on
pcl - The PropertyChangeListener to be added

===

public void removePropertyChangeListener(String name,
                                         PropertyChangeListener pcl)
Remove a property change listener. 

Specified by:
removePropertyChangeListener in interface BeanContextChild
Parameters:
name - The name of the property that was listened on
pcl - The PropertyChangeListener to be removed

===

public void addVetoableChangeListener(String name,
                                      VetoableChangeListener vcl)
Adds a VetoableChangeListener. 

Specified by:
addVetoableChangeListener in interface BeanContextChild
Parameters:
name - The name of the property to listen on
vcl - The VetoableChangeListener to be added

===

public void removeVetoableChangeListener(String name,
                                         VetoableChangeListener vcl)
Removes a VetoableChangeListener. 

Specified by:
removeVetoableChangeListener in interface BeanContextChild
Parameters:
name - The name of the property that was listened on
vcl - The VetoableChangeListener to be removed

...
---------- end-of-excerpt ---------------

Problem description
===================
The spec for the designated 4 methods does not say about the
expected behaviour in cases:

1. addPropertyChangeListener(String name,
                                      PropertyChangeListener pcl)
   if name == null;

2. addPropertyChangeListener(String name,
                                      PropertyChangeListener pcl)
   if pcl == null;

3. addPropertyChangeListener(String name,
                                      PropertyChangeListener pcl)
  if pcl has already been added;

4. public void removePropertyChangeListener(String name,
                                         PropertyChangeListener pcl)
  if name == null;

5. public void removePropertyChangeListener(String name,
                                         PropertyChangeListener pcl)
  if pcl == null;

6. public void removePropertyChangeListener(String name,
                                         PropertyChangeListener pcl)
  if there is no such listener as pcl;

7. public void removePropertyChangeListener(String name,
                                         PropertyChangeListener pcl)
  if pcl has been added regarding another property name;

8. The same 7 points about add/removeVetoableChangeListener methods

Please refer to the "Requirements for Writing Java API Specifications"
 (http://java.sun.com/j2se/javadoc/writingapispecs/index.html#method)
for more information.


JCK test source location:
==========================
/java/re/jck/1.5/promoted/latest/JCK-runtime-15/tests

======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta2 FIXED IN: tiger-beta2 INTEGRATED IN: tiger-b41 tiger-beta2 VERIFIED IN: tiger-b40
14-06-2004

EVALUATION ###@###.### 2003-10-16 The null parameters are addressed in Tiger at the package level. The other issues will be documented in this class. ###@###.### 2003-10-27 As with bug 4937059, most of these items are already covered by the Beans spec and/or the java.beans package docs. Items 1 and 4 are covered under the new bug, 4985020. Items 2 and 5 are covered by the package level statement, "Unless explicitly stated, null values or empty Strings are not valid parameters for the methods in this package. You may expect to see exceptions if these parameters are used." Items 3 is covered in section 6.5 of the Beans spec: "The relationship between registration order and event delivery order is implementation defined. In addition the effects of adding the same event listener object more than once on the same event source, or of removing an event listener object more than once, or of removing an event listener object that is not registered, are all implementation defined." I'm not sure what is meant by 6. Assuming it is asking what happens when a listener is attempted to be removed from an event source that it was never registered with, then this is also covered by the Beans spec, like item 3. Item 7 should be specified as such: "Attempting to remove a listener on a property for which it was never registered results in no action being taken." The above are all true of VetoableChangeListeners as well. To make this clearer, I'll add some references to the JavaBeans Spec to the methods in question. ###@###.### 2004-01-30 Upon further discussion, we feel it is a better strategy to more explicitly specify the correct behavior in the JavaDoc. This is in line with our solution to similar bug 4937059. ###@###.### 2004-02-04
04-02-2004

SUGGESTED FIX ------- BeanContextChildSupport.java ------- *** /tmp/sccs.pPaysm Wed Feb 4 17:00:08 2004 --- BeanContextChildSupport.java Tue Feb 3 20:04:18 2004 *************** *** 127,133 **** public synchronized BeanContext getBeanContext() { return beanContext; } /** ! * Adds a property change listener. * @param name The name of the property to listen on * @param pcl The <code>PropertyChangeListener</code> to be added */ --- 127,139 ---- public synchronized BeanContext getBeanContext() { return beanContext; } /** ! * Add a PropertyChangeListener for a specific property. ! * The same listener object may be added more than once. For each ! * property, the listener will be invoked the number of times it was added ! * for that property. ! * If <code>pcl</code> is null, no exception is thrown and no action ! * is taken. ! * * @param name The name of the property to listen on * @param pcl The <code>PropertyChangeListener</code> to be added */ *************** *** 136,142 **** } /** ! * Remove a property change listener. * @param name The name of the property that was listened on * @param pcl The PropertyChangeListener to be removed */ --- 142,152 ---- } /** ! * Remove a PropertyChangeListener for a specific property. ! * ! * If <code>pcl</code> is null, or was never added for the specified ! * property, no exception is thrown and no action is taken. ! * * @param name The name of the property that was listened on * @param pcl The PropertyChangeListener to be removed */ *************** *** 145,151 **** } /** ! * Adds a <code>VetoableChangeListener</code>. * @param name The name of the property to listen on * @param vcl The <code>VetoableChangeListener</code> to be added */ --- 155,166 ---- } /** ! * Add a VetoableChangeListener for a specific property. ! * The same listener object may be added more than once. For each ! * property, the listener will be invoked the number of times it was added ! * for that property. ! * If <code>vcl</code> is null, no exception is thrown and no action ! * is taken. * @param name The name of the property to listen on * @param vcl The <code>VetoableChangeListener</code> to be added */ *************** *** 155,160 **** --- 170,179 ---- /** * Removes a <code>VetoableChangeListener</code>. + * + * If <code>vcl</code> is null, or was never added for the specified + * property, no exception is thrown and no action is taken. + * * @param name The name of the property that was listened on * @param vcl The <code>VetoableChangeListener</code> to be removed */ ------- VetoableChangeSupport.java ------- *** /tmp/sccs.akaytm Wed Feb 4 17:00:34 2004 --- VetoableChangeSupport.java Tue Feb 3 20:04:16 2004 *************** *** 45,50 **** --- 45,54 ---- /** * Add a VetoableListener to the listener list. * The listener is registered for all properties. + * The same listener object may be added more than once, and will be called + * as many times as it is added. + * If <code>listener</code> is null, no exception is thrown and no action + * is taken. * * @param listener The VetoableChangeListener to be added */ *************** *** 51,56 **** --- 55,63 ---- public synchronized void addVetoableChangeListener( VetoableChangeListener listener) { + if (listener == null) { + return; + } if (listener instanceof VetoableChangeListenerProxy) { VetoableChangeListenerProxy proxy = (VetoableChangeListenerProxy)listener; *************** *** 69,79 **** --- 76,91 ---- * Remove a VetoableChangeListener from the listener list. * This removes a VetoableChangeListener that was registered * for all properties. + * If <code>listener</code> is null, or was never added, no exception is + * thrown and no action is taken. * * @param listener The VetoableChangeListener to be removed */ public synchronized void removeVetoableChangeListener( VetoableChangeListener listener) { + if (listener == null) { + return; + } if (listener instanceof VetoableChangeListenerProxy) { VetoableChangeListenerProxy proxy = (VetoableChangeListenerProxy)listener; *************** *** 128,133 **** --- 140,150 ---- * Add a VetoableChangeListener for a specific property. The listener * will be invoked only when a call on fireVetoableChange names that * specific property. + * The same listener object may be added more than once. For each + * property, the listener will be invoked the number of times it was added + * for that property. + * If <code>listener</code> is null, no exception is thrown and no action + * is taken. * * @param propertyName The name of the property to listen on. * @param listener The VetoableChangeListener to be added *************** *** 135,155 **** public synchronized void addVetoableChangeListener( String propertyName, ! VetoableChangeListener listener) { ! if (children == null) { ! children = new java.util.Hashtable(); ! } ! VetoableChangeSupport child = (VetoableChangeSupport)children.get(propertyName); ! if (child == null) { ! child = new VetoableChangeSupport(source); ! children.put(propertyName, child); ! } ! child.addVetoableChangeListener(listener); } /** * Remove a VetoableChangeListener for a specific property. * * @param propertyName The name of the property that was listened on. * @param listener The VetoableChangeListener to be removed */ --- 152,178 ---- public synchronized void addVetoableChangeListener( String propertyName, ! VetoableChangeListener listener) { ! if (listener == null) { ! return; ! } ! if (children == null) { ! children = new java.util.Hashtable(); ! } ! VetoableChangeSupport child = (VetoableChangeSupport)children.get(propertyName); ! if (child == null) { ! child = new VetoableChangeSupport(source); ! children.put(propertyName, child); ! } ! child.addVetoableChangeListener(listener); } /** * Remove a VetoableChangeListener for a specific property. * + * If <code>listener</code> is null, or was never added for the specified + * property, no exception is thrown and no action is taken. + * * @param propertyName The name of the property that was listened on. * @param listener The VetoableChangeListener to be removed */ *************** *** 156,170 **** public synchronized void removeVetoableChangeListener( String propertyName, ! VetoableChangeListener listener) { ! if (children == null) { ! return; ! } ! VetoableChangeSupport child = (VetoableChangeSupport)children.get(propertyName); ! if (child == null) { ! return; ! } ! child.removeVetoableChangeListener(listener); } /** --- 179,196 ---- public synchronized void removeVetoableChangeListener( String propertyName, ! VetoableChangeListener listener) { ! if (listener == null) { ! return; ! } ! if (children == null) { ! return; ! } ! VetoableChangeSupport child = (VetoableChangeSupport)children.get(propertyName); ! if (child == null) { ! return; ! } ! child.removeVetoableChangeListener(listener); } ###@###.### 2004-02-04
04-02-2004