United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4950122 LTP: DefaultPersistenceDelegate does not handle boolean properties in a superclass.
JDK-4950122 : LTP: DefaultPersistenceDelegate does not handle boolean properties in a superclass.

Details
Type:
Bug
Submit Date:
2003-11-06
Status:
Closed
Updated Date:
2010-07-09
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
client-libs
OS:
linux,solaris_nevada,windows_xp,windows_2000
Sub-Component:
java.beans
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
1.4.1,1.4.2,6
Fixed Versions:

Related Reports
Backport:
Duplicate:
Relates:

Sub Tasks

Description
Name: jl125535			Date: 11/06/2003


FULL PRODUCT VERSION :
All 1.4.x releases.

FULL OS VERSION :
Applicable to all.

A DESCRIPTION OF THE PROBLEM :
The DefaultPersistenceDelegate does not correctly search for boolean properties if they are in a superclass.  The following code (line 162 in 1.4.2) illustrates the problem:

constructorArgs[i] = (f != null && !Modifier.isStatic(f.getModifiers())) ?
                    f.get(oldInstance) :
                    type.getMethod("get"+capitalize(name), new Class[0]).invoke(oldInstance, new Object[0]);

In the case that type == boolean/Boolean, the code should check for "is"+capatalize(name) and then fall back on "get" if that fails.

Section 8.3.2 of the JavaBeans Specification at http://java.sun.com/products/javabeans/docs/spec.html describes the "is<PropertyName>" naming pattern for boolean properties.

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


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.beans.XMLEncoder;
import java.beans.DefaultPersistenceDelegate;
import java.io.ByteArrayOutputStream;

public class DefaultPersistenceDelegateBug {

    public static class SuperBean {
        private boolean condition;

        public SuperBean(boolean condition) {
            this.condition = condition;
        }

        public boolean isCondition() {
            return condition;
        }
    }

    public static class SubBean extends SuperBean {
        public SubBean(boolean condition) {
            super(condition);
        }
    }

    public static void main(String[] args) {
        XMLEncoder encoder = new XMLEncoder(new ByteArrayOutputStream());
        encoder.setPersistenceDelegate(SubBean.class, new DefaultPersistenceDelegate(new String[]{"condition"}));
        encoder.writeObject(new SubBean(true));
    }
}

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

CUSTOMER SUBMITTED WORKAROUND :
If you have access to your beans, then you can add/change your boolean getter to be in "get" pattern instead of the "is" pattern.
(Incident Review ID: 207880) 
======================================================================

Name: jl125535			Date: 11/06/2003


DESCRIPTION OF THE PROBLEM :
Below is a test case.  I have two classes that I want to persist.

Test1 has a boolean value that is set by the constructor and can be accessed by isSomething().

Test2 extends Test1 and adds some more behaviour.

  To persist objects of both classes I create an XMLEncoder and add DefaultPersistenceDelegate's for both classes, telling them that they should get the value of the something-attribute.

I can persist objects of class Test1. However if I try to persist objects of class Test2 I get "java.lang.NoSuchMethodException: Test2.getSomething()"

According to the JavaBeans specification boolean attributes can be accessed either by getXXX or by isXXX. DefaultPersistenceDelegate should support both methods.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
DefaultPersistenceDelegate should use the field itself or either method "getSomething" or "isSomething".
ACTUAL -
DefaultPersistenceDelegate uses the field itself or just "getSomething".

---------- BEGIN SOURCE ----------
import java.beans.DefaultPersistenceDelegate;
import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {

	public static void main(String[] args) throws IOException {
		XMLEncoder e = new XMLEncoder(
			new BufferedOutputStream(
				new FileOutputStream("Test.xml")));

		e.setPersistenceDelegate(Test1.class,
			new DefaultPersistenceDelegate(new String[]{"something"}));
		e.setPersistenceDelegate(Test2.class, new 			DefaultPersistenceDelegate(new String[]{"something"}));
		e.writeObject(new Test1(true));
		e.writeObject(new Test2(true));
		e.flush();
		e.close();
	}
}

public class Test1 {
	private boolean something;

	public Test1(boolean something) {
		this.something = something;
	}
	
	public boolean isSomething() {
		return something;
	}
}

public class Test2 extends Test1 {
	public Test2(boolean something) {
		super(something);
	}
}

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

CUSTOMER SUBMITTED WORKAROUND :
If you may modify either Test1 or Test2 then add a method getSomething().

Otherwise create your own PersistenceDelegate that reads all attributes.
(Review ID: 209682)
======================================================================

                                    

Comments
EVALUATION

Persistence delegates should adhere to the Beans specification and precedence should be for the "is" method. Not a showstopper for tiger but may be put into tiger if this is a critical issue.

###@###.### 2003-11-11
                                     
2003-11-11
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
dragon


                                     
2004-06-14
EVALUATION

We should use Introspector to find getters for the property,
because getter for the property can have other name than "getPropertyName()".
                                     
2006-12-20



Hardware and Software, Engineered to Work Together