I recently had a problem with a bean which causes the "No getter method for property..." when used with the <bean:write> tag.
Surfing the web, I found the message posted October 27, 2004 09:41 AM in this forum by Erick Reid. The topic was "No getter method for property... (but not the usual suspects)".
Interestingly, Erick suggested using a
bean dump util to get insight about a bean's exposed properties.
Using it I discovered that the problem wasn't
Struts Tag's responsability, but Introspector's. Basically, it's due to the the Introspector's default way of finding the BeanInfo.
I've found the following post by Dawid Weiss in comp.lang.java.programmer. He reports the very same problem and clearly explains what's going on.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Newsgroup: comp.lang.java.programmer
From:
dawid.we...@cs.put.poznan.pl (Dawid Weiss)
Date: 20 Feb 2003.02.20 03:41:41 -0800
Subject: JDK 'feature' in java.beans.Introspector prevents accessing properties of classes named Component
I've just spent 3 hours trying to find a bug in my STRUTS application.
As it turned out, it was neither my fault, nor STRUTS. It's just undocumented (or maybe documented, but I'm not aware of it) 'feature' of java.beans.Introspector class, used by STRUTS to access properties of
java beans.
The bug (?) only shows up when your class is named "Component", no matter what package it is in and does not have any associated beaninfo class. Then the 'discovered' set of properties will NOT be that of your class, but java.awt.Component...
Is this a bug? A feature? This should at least have a mention in the docs, right?
Dawid
--
Try this: create a java bean in you own package and name it "Component", for example:
com.bubu.dede.Component
Create several setters and getters, as you wish. Now, try to use it
with STRUTS and use automatic introspection (
JSP tags). It won't work and you'll get a message saying "no property xxx in bean yyy". So you dig in STRUTS code and see that it's using standard Java Introspection class. Amazed, you type the following code:
BeanInfo beanInfo = Introspector.getBeanInfo(myBean.getClass());
PropertyDescriptor [] descriptors = beanInfo.getPropertyDescriptors();
for (int i=0;i<descriptors.length;i++)
System.out.println("property: " + descriptors[i].getName());
And the properties you see discovered are not at all those, which you declared.
Why is that? Because Introspector's getBeanInfo uses the default: USE_ALL_BEANINFO, which should check also BeanInfo classes from up the hierarchy of your bean's classes. Unfortunately, which is mentioned in the documentation, but quite vague, Introspector also uses "search path" to look for BeanInfos:
"We first look for the BeanInfo class by taking the full package-qualified name of the target bean class and appending "BeanInfo" to form a new class name. If this fails, then we take the final classname component of this name, and look for that class in each of the packages specified in the BeanInfo package search path."
This search path is declared as (JDK1.4.0_03):
private static
String[] searchPath = { "sun.beans.infos" };
A quick look into the rt.jar reveals, that there is a class ComponentBeanInfo, which describes java.awt.Component java Bean. This way, your component's real properties are never revealed to the introspection mechanism.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx