-
Bug
-
Resolution: Unresolved
-
P4
-
8, 8u25, 9
-
x86
-
windows_7
FULL PRODUCT VERSION :
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) Client VM (build 25.25-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
PropertyDescriptor.getReadMethod() returns 'null' for the read method of a Boolean property of a class that its declaration has a 'is' prefix instead of 'get' though the respective MethodDescriptor.getMethod().getName() for the same property is returned as would be expected. Probably it is a bug in the Introspector class. The problem was discovered while working with Vaadin and trying to bind a checkbox to a BeanItem (object of Vaadin) that has Boolean properties with 'is' prefixed getters.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Declare a class like the following:
class myClass implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
public myClass()
{
}
Boolean active;
public Boolean isActive()
{
return active;
}
public void setActive(Boolean active)
{
this.active = active;
}
Boolean valid;
public Boolean getValid()
{
return active;
}
public void setValid(Boolean valid)
{
this.valid = valid;
}
}
create a JUnit test with the following method
@Test
public void testBeanProblem()
{
BeanInfo in;
try {
in = Introspector.getBeanInfo(myClass.class);
System.out.println("---=== MethodDescriptor ===---");
for(MethodDescriptor md:in.getMethodDescriptors())
{
if(md.getMethod()!=null)
System.out.println(md.getMethod().getName());
}
System.out.println("---=== PropertyDescriptor and getReadMethod ===---");
for(PropertyDescriptor pd:in.getPropertyDescriptors())
{
System.out.println(pd.getName() + " *** " + pd.getReadMethod());
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
The output will be:
---=== MethodDescriptor ===---
getClass
isActive
getValid
wait
notifyAll
notify
wait
hashCode
setValid
setActive
wait
equals
toString
---=== PropertyDescriptor and getReadMethod ===---
active *** null
class *** public final native java.lang.Class java.lang.Object.getClass()
valid *** public java.lang.Boolean gr.moralis.tests.BeanErrorTest$myClass.getValid()
As you can see, the 'active' property descriptor returns a null value for read method. That doesn't happen for the 'valid' property for which the getter is prefixed with the 'get' prefix instead of the 'is' prefix which is more usual for Boolean properties.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
We should get
active *** gr.moralis.tests.BeanErrorTest$myClass.isActive()
ACTUAL -
We get
active *** null
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package gr.moralis.tests;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import org.junit.Test;
public class BeanErrorTest{
class myClass implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
public myClass()
{
}
Boolean active;
public Boolean isActive()
{
return active;
}
public void setActive(Boolean active)
{
this.active = active;
}
Boolean valid;
public Boolean getValid()
{
return active;
}
public void setValid(Boolean valid)
{
this.valid = valid;
}
}
@Test
public void testBeanProblem()
{
BeanInfo in;
try {
in = Introspector.getBeanInfo(myClass.class);
System.out.println("---=== MethodDescriptor ===---");
for(MethodDescriptor md:in.getMethodDescriptors())
{
if(md.getMethod()!=null)
System.out.println(md.getMethod().getName());
}
System.out.println("---=== PropertyDescriptor and getReadMethod ===---");
for(PropertyDescriptor pd:in.getPropertyDescriptors())
{
System.out.println(pd.getName() + " *** " + pd.getReadMethod());
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The only workaround is to use 'get' prefixes for Boolean property getter instead of the usual 'is' prefix, but this limits the use of automatic code generation tools.
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) Client VM (build 25.25-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
PropertyDescriptor.getReadMethod() returns 'null' for the read method of a Boolean property of a class that its declaration has a 'is' prefix instead of 'get' though the respective MethodDescriptor.getMethod().getName() for the same property is returned as would be expected. Probably it is a bug in the Introspector class. The problem was discovered while working with Vaadin and trying to bind a checkbox to a BeanItem (object of Vaadin) that has Boolean properties with 'is' prefixed getters.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Declare a class like the following:
class myClass implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
public myClass()
{
}
Boolean active;
public Boolean isActive()
{
return active;
}
public void setActive(Boolean active)
{
this.active = active;
}
Boolean valid;
public Boolean getValid()
{
return active;
}
public void setValid(Boolean valid)
{
this.valid = valid;
}
}
create a JUnit test with the following method
@Test
public void testBeanProblem()
{
BeanInfo in;
try {
in = Introspector.getBeanInfo(myClass.class);
System.out.println("---=== MethodDescriptor ===---");
for(MethodDescriptor md:in.getMethodDescriptors())
{
if(md.getMethod()!=null)
System.out.println(md.getMethod().getName());
}
System.out.println("---=== PropertyDescriptor and getReadMethod ===---");
for(PropertyDescriptor pd:in.getPropertyDescriptors())
{
System.out.println(pd.getName() + " *** " + pd.getReadMethod());
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
The output will be:
---=== MethodDescriptor ===---
getClass
isActive
getValid
wait
notifyAll
notify
wait
hashCode
setValid
setActive
wait
equals
toString
---=== PropertyDescriptor and getReadMethod ===---
active *** null
class *** public final native java.lang.Class java.lang.Object.getClass()
valid *** public java.lang.Boolean gr.moralis.tests.BeanErrorTest$myClass.getValid()
As you can see, the 'active' property descriptor returns a null value for read method. That doesn't happen for the 'valid' property for which the getter is prefixed with the 'get' prefix instead of the 'is' prefix which is more usual for Boolean properties.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
We should get
active *** gr.moralis.tests.BeanErrorTest$myClass.isActive()
ACTUAL -
We get
active *** null
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package gr.moralis.tests;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import org.junit.Test;
public class BeanErrorTest{
class myClass implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
public myClass()
{
}
Boolean active;
public Boolean isActive()
{
return active;
}
public void setActive(Boolean active)
{
this.active = active;
}
Boolean valid;
public Boolean getValid()
{
return active;
}
public void setValid(Boolean valid)
{
this.valid = valid;
}
}
@Test
public void testBeanProblem()
{
BeanInfo in;
try {
in = Introspector.getBeanInfo(myClass.class);
System.out.println("---=== MethodDescriptor ===---");
for(MethodDescriptor md:in.getMethodDescriptors())
{
if(md.getMethod()!=null)
System.out.println(md.getMethod().getName());
}
System.out.println("---=== PropertyDescriptor and getReadMethod ===---");
for(PropertyDescriptor pd:in.getPropertyDescriptors())
{
System.out.println(pd.getName() + " *** " + pd.getReadMethod());
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The only workaround is to use 'get' prefixes for Boolean property getter instead of the usual 'is' prefix, but this limits the use of automatic code generation tools.