Search code examples
javaintrospectionjavabeans

JavaBeans and introspection - messed up on boolean and indexed properties?


A former colleague of mine started a discussion half an hour ago about JavaBeans, and why they didn't quite work the way he wants in JSF. The particular case is about boolean properties.

1. For a boolean property named isUrl Eclipse generates this

private boolean isUrl;
public boolean isUrl() {..}
public boolean setUrl(boolean url) {..}

But this does not work in JSF. He made it work by adding public boolean getIsUrl() The implementation might be buggy, so let's make sure who's right, by using the introspection API.:

BeanInfo info = Introspector.getBeanInfo(ClassTest.class);
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
      System.out.println(pd.getName() + ": " + pd.getReadMethod() + 
       " : " + pd.getWriteMethod());
}

For the above code, this prints both methods - i.e. Eclipse is right, JSF is wrong. But that sounded suspicious to me, since the specification doesn't mention anything about the double "is".

But while looking through the spec, I saw something I've never used - the so called indexed properties. You can have private String[] bar and then public String getBar(int idx). So:

2. I tried that with the Introspector, and it didn't find a read method for bar. The result from the above code was: bar: null : null. So I came to think - now the introspector does not follow the spec. Perhaps it didn't follow it in the previous case, and ultimately, JSF is right. In fact, indexed properties can make so that there are two read methods for a given property. And that's not possible with the PropertyDescriptor class of the introspection API.

What does this lead us to - we have a possibly broken API that does not conform to the spec. Which leads to other implementations of the spec (JSF uses a custom one obviously). Which leads to further misunderstandings and confusions.

A sidenote for something that bothered me - in the JavaBeans spec they call the naming conventions for the methods "design patterns". This sounds wrong to me.

So, now onto the questions:

  1. is the JavaBeans spec clear
  2. is the introspection API correct
  3. is a new JavaBeans specification needed, at least to clarify the behaviour of booleans (that's subjective to an extent)

Update. it appears the JSF usage is bean.isUrl rathern than bean.url. Which makes perfects sense not to work with isUrl() accessor.

P.S. JDK 1.6.0_20, JSF 1.2, MyFaces


Solution

  • As mentioned by @Peter Lawrey, the name of the field is irrelevant as far as JavaBeans is concerned. It needn't even exist, or you can give it a silly name such as prefixing with m_.

    You didn't provide a suitable read or write methods for the bar property as a whole, so these are not going to show up. You can't synthesize a Method to an existing class at runtime. I believe indexed properties were a late edition, even though there isn't an @since apparent, so they aren't used by java.beans interfaces.

    I don't have the JSF spec (and it'll be behind the jcp.org lawyer wall), so don't know what it claims. It may specify something different to the JavaBeans spec [probable], or you may be using an implementation with bugs [I guess also probable].

    "Design pattern" is just a phrase. As in a pattern that occurs in our design. It's not Design Pattern as in GoF.