• Home
  • RSS Feed
  • Log in

Gotcha! Watch out when overriding bean property accessors…
Posted by Andrew Phillips in the early morning: March 6th, 2009

Whilst working on a bean deep cloning utility recently (more about that some other time) I got stuck for a while on some unexpected behaviour exhibited by java.beans.Introspector. I don't know many people who use this class directly, but it's heavily used by, amongst others, the Apache BeanUtils, so if you're using those you might still come across this issue.

The problem arises if you happen to have overridden bean property accessors in your classes.
For instance, assume you have a base class NumberHolder:

public class NumberHolder {
  private Number number;
  public Number getNumber() { return number; }
  public void setNumber(Number number) { this.number = number; }
}

Say that, within a certain context in your application, you know that the NumberHolder will always contain a Long. Then you could keep doing

Long long = (Long) myHolder.getNumber();

but that's rather ugly. So you might create a LongHolder:

public class LongHolder extends NumberHolder {
  @Override
  public Long getNumber() { return (Long) super.getNumber(); }
}

Now the million-dollar question is: Is LongHolder's number property writable or not? It certainly has a setter that accepts a Number and a getter that returns a Number (subclass), but on the other hand it doesn't have a setter that accepts a Long, and the property itself isn't a Long, either.
[Aside: I'm no longer sufficiently familiar with the intricacies of the Beans spec to be sure if the overriding getNumber() method isn't a violation. Any comments on that subject would be interesting.]

Whichever way, one would expect that the answer is either "yes" or "no". Unfortunately, though, the current reality appears to be: "Well, it depends."

Depends, in fact, on what kind of mood Class.getDeclaredMethods is in; to wit: in which order it returns the two getNumber() methods of LongHolder. Introspector retrieves these methods in order to be able to pair up possible getters and setters and thus determine the read-/writability of the bean properties.

If LongHolder.getNumber comes first, it is "overwritten" in the Introspector's data structure by NumberHolder.getNumber, for which a matching setter is found (correct name, same type), so the property is writable.
If, however, NumberHolder.getNumber comes first...well, you can, no doubt, guess what happens: no matching setter is found (there is no setNumber(Long) method in either of the classes) and so the property is not writable.

...and since the the order of the methods returned by Class.getDeclaredMethods is documented as being undetermined, this is a bug (6807471, in fact).

So if you're overriding property accessors in your code anywhere, you might want to bear this in mind.

Incidentally, it looks like there have been plenty of issues related to the indeterminate order of Class.getDeclaredMethods already, the bug reports for some of which contain very detailed discussions about the difficulty of mandating an ordering. Still, I'm surprised this hasn't been addressed yet.

  • Share/Bookmark

Tags: beans, beanutils, bug, Java
Filed under Java | No Comments »



No Responses to “Gotcha! Watch out when overriding bean property accessors…”



Leave a Reply

Click here to cancel reply.

Deployment automation for Java application running on Websphere, WebLogic and JBoss

Archives

  • March 2010
  • February 2010
  • January 2010
  • December 2009
  • November 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009

Xebia Sites

  • Xebia Corporate
  • Xebia France
  • Xebia India

Categories

  • Java (282)
  • Agile (109)
  • General (50)
  • Testing (42)
  • Performance (42)
  • Hibernate (36)
  • Scrum (33)
  • Podcast (31)
  • Architecture (31)
  • Spring (28)
  • SOA (24)
  • Maven (22)
  • Project Management (22)
  • Middleware (23)
    • Deployment (14)
  • Flex (17)
  • JPA (17)
  • Eclipse (15)
  • Xebia Labs (15)
  • Quality Assurance (14)

Tag Cloud

    qcon fitnesse Grails Agile Awareness Workshop Introduction to Agile SOA Functional Programming Groovy Agile Scrum Testing Scala Maven Java Xebia Seam Lean IntelliJ Performance Spring Hibernate Closures esb XML Ajax Architecture product owner Poppendieck JavaOne Semantic Web