JDK-4950122 : LTP: DefaultPersistenceDelegate does not handle boolean properties in a superclass.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.beans
  • Affected Version: 1.4.1,1.4.2,6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS:
    linux,solaris_nevada,windows_2000,windows_xp linux,solaris_nevada,windows_2000,windows_xp
  • CPU: generic,x86
  • Submitted: 2003-11-06
  • Updated: 2010-07-09
  • Resolved: 2011-03-08
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.
JDK 6 JDK 7
6u2Fixed 7 b07Fixed
Related Reports
Duplicate :  
Relates :  
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 We should use Introspector to find getters for the property, because getter for the property can have other name than "getPropertyName()".
20-12-2006

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: dragon
14-06-2004

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
11-11-2003