JDK-4996673 : Introspector cloning PropertyDescriptors when not needing to.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.beans
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2004-02-18
  • Updated: 2009-02-26
Related Reports
Relates :  
Description
Name: gm110360			Date: 02/18/2004


FULL PRODUCT VERSION :
java version "1.4.2_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_03-b02)
Java HotSpot(TM) Client VM (build 1.4.2_03-b02, mixed mode)

FULL OS VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
In Introspector.processPropertyDescriptors, the piece of code starting with:

	    list = (List)it.next();

	    // First pass. Find the latest getter method. Merge properties
	    // of previous getter methods.
	    for (int i = 0; i < list.size(); i++) {
		pd = (PropertyDescriptor)list.get(i);
		if (pd instanceof IndexedPropertyDescriptor) {
                       ...
	    pd = null; ipd = null;

	    if (igpd != null && ispd != null) {
		// Complete indexed properties set
		// Merge any classic property descriptors
		if (gpd != null && (gpd.getPropertyType().isArray() ||
				       gpd.getPropertyType().equals(igpd.getIndexedPropertyType()))) {
		    igpd = new IndexedPropertyDescriptor(gpd, igpd);
		}
		if (spd != null && (spd.getPropertyType().isArray() ||
				    spd.getPropertyType().equals(ispd.getIndexedPropertyType()))) {
		    ispd = new IndexedPropertyDescriptor(spd, ispd);
                 ...

causes the incoming property descriptors to be cloned because it is expecting that the list will have more than one entry for the given property, and it is trying to merge them to produce one viable property descriptor. The problem is that 99% of the time the size of the list for the given property is just one, and there is no need to go through this. What happens is if there is only one property descriptor in the list it winds up doing "pd = new PropertyDescriptor(gpd, spd);" where gpd and spd are the same object.

There should be a test at the beginning that if the list size is one, just take the one entry and make it the final PropertyDescriptor.

The reason this is giving me a problem is because I'm trying to determine which properties returned from an introspection are from a superclass, and which were introduced at the current class. If the properties weren't always cloned, I can do a simple equals(). Since they are cloned, I have to do a more complicated check of the contents to see if came from the super class.


REPRODUCIBILITY :
This bug can be reproduced always.
(Incident Review ID: 182758) 
======================================================================

Comments
EVALUATION The code in question has changed in 1.5 when bug 4918902 was fixed. The code snippet now looks like: if (igpd != null && ispd != null) { // Complete indexed properties set // Merge any classic property descriptors if (gpd != null) { PropertyDescriptor tpd = mergePropertyDescriptor(igpd, gpd); if (tpd instanceof IndexedPropertyDescriptor) { igpd = (IndexedPropertyDescriptor)tpd; } } if (spd != null) { PropertyDescriptor tpd = mergePropertyDescriptor(ispd, spd); if (tpd instanceof IndexedPropertyDescriptor) { ispd = (IndexedPropertyDescriptor)tpd; } } ... I encourage you to give tiger a try (post b28). ###@###.### 2004-02-26
26-02-2004