You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@jakarta.apache.org by Damian Fauth <df...@access.fairfax.com.au> on 2000/03/16 15:00:58 UTC

JspRuntimeLibrary.java broke my taglib!

Hi,

I recently upgraded from Tomcat 3.1m1 to 3.1beta1 and found that a
number of my custom tags were broken by the new JspRunTimeLibrary class. 

The problem is the use of multiple 'setProperty()' methods for a single
property in a custom tag. 

I have a number of such tags for rendering HTML form elements from beans
and they can have both Enumeration and Hashtable objects assigned to the
'values' property - this is where the multiple 'setProperty()' methods
come from - setValues(java.util.Enumeration) and
setValues(java.util.Hashtable). 

So for example, using the bean:
  <jsp:useBean id="stateHash" scope="application"
class="java.util.Hashtable"/>
the same tag can be used like this:
  <form:select name="state" values="<%= stateHash.elements() %>"
selected="Western Australia"/>
or like this:
  <form:select name="state" values="<%= stateHash %>" selected="WA"/>


The getWriteMethod(Class beanClass, String prop) method in
JspRuntimeLibrary.java steps through the beans properties looking for
the matching property in order to get its write method, however
PropertyDescriptor.getWriteMethod() is used to get the write method and
which one it returns seems indeterminite, consequently I am getting an
IllegalArgumentException

My question: is my taglib consistent with the spec? Can a property of a
bean have more than one 'set' method signature? If so, the following
diff may be the basis for a patch - at least it works for my test cases
(my custom tags) and for the taglib example packaged with tomcat.

I can provide some test cases (tag class + jsp) if you need it.

TIA,

Damian

PS. Sorry if this is the wrong mailing list, its the only one I am
subscribed to.


--- JspRuntimeLibrary.java.bak  Wed Jan 12 18:11:16 2000
+++ JspRuntimeLibrary.java      Fri Mar 17 00:23:41 2000
@@ -445,7 +445,7 @@
        throws JasperException
     {
        try {
-            Method method = getWriteMethod(bean.getClass(), prop);
+            Method method = getWriteMethod(bean.getClass(), prop,
value.getClass());
            method.invoke(bean, new Object[] { value });
        } catch (Exception ex) {
            throw new JasperException(ex);
@@ -550,21 +550,59 @@
     
     public static java.lang.reflect.Method getWriteMethod(Class
beanClass, String prop)
     throws JasperException {
-       java.lang.reflect.Method method = null; 
+        return getWriteMethod(beanClass, prop, null);
+    }
+
+    public static java.lang.reflect.Method getWriteMethod(Class
beanClass, String prop, Class propClass)
+    throws JasperException {
+        java.lang.reflect.Method method = null;
+        String methodName = null;
         Class type = null;
+
        try {
            java.beans.BeanInfo info
                 = java.beans.Introspector.getBeanInfo(beanClass);
            if ( info != null ) {
+
+                // find the name of the write method
                java.beans.PropertyDescriptor pd[]
                    = info.getPropertyDescriptors();
                for (int i = 0 ; i < pd.length ; i++) {
                    if ( pd[i].getName().equals(prop) ) {
-                       method = pd[i].getWriteMethod();
-                       type   = pd[i].getPropertyType();
-                       break;
+                       methodName = pd[i].getWriteMethod().getName();
+                        break;
                    }
                }
+
+               java.beans.MethodDescriptor md[]
+                   = info.getMethodDescriptors();
+               for (int i = 0 ; i < md.length ; i++) {
+                   if ( md[i].getName().equals(methodName) ) {
+
+                       method = md[i].getMethod();
+
+                        // check the class of its parameters
+                        Class paramClass[] =
method.getParameterTypes();
+
+                        // there should only ever be one?!?
+                        if(paramClass[0].isInterface()) {
+                            Class interfaces[] =
propClass.getInterfaces();
+
+                            // look for one that matches
+                            for(int j=0;j<interfaces.length;j++) {
+                                if( paramClass[0] == interfaces[j] ) {
+                                    break;
+                                }
+                            }
+                        } else {
+                            if ( propClass == paramClass[0] ) {
+                               break;
+                            }
+                        }
+
+                   }
+               }
+
             } else {        
                 // just in case introspection silently fails.
                 throw new JasperException(Constants.getString(

Re: JspRuntimeLibrary.java broke my taglib!

Posted by Damian Fauth <df...@access.fairfax.com.au>.
Actually, I submitted this as a bug last night - #109.

I had a quick look in the 1.01 beans spec, but could find nothing
referring to multiple setter methods at all, so it seems to me it is
unclear on this point. The getWriteMethod() of PropertyDescriptor is
described as returning "...the method that should be used to write the
property value. May return null if the property can't be written". Is
there something more against it that I have missed? Otherwise it would
seem to be a matter of interpretation, and I agree its a very useful and
flexible feature for taglibs to have.

Damian

Hans Bergsten wrote:
> 
> Hi guys,
> 
> I responded to the message below on the general@jakarta.apache.org a while ago,
> but since no one picked it up I decided to try to apply the patch myself today.
> But looking at this in more detail, I'm not sure if the behavior Damian
> describes
> (present in a Tomcat 3.1m1, removed in 3.1beta1) is really valid according to
> the JSP and JavaBeans specs.
> 
> What it boils down to is whether a bean property can have multiple setter
> methods, all with different types, or if there must only be one setter method
> with a type matching the getter method (id any). It's extremely useful
> (especially
> for custom actions), but from reading the JavaBeans spec and looking at the
> java.beans.PropertyDescriptor class I'm pretty sure it's "illegal".
> 
> A typical example of where this is useful is for a custom action with a
> request-time attribute that can be set to many different types (e.g. int,
> long, Date, etc.), such as the value to use in a JDBC PreparedStatement.
> 
> I would appreciate if someone can clarify if this is spec compliant or not.
> If it is, I have a patch ready for Tomcat but a clarification may also be
> needed in the JSP spec. If not, I have some rework on my SQL tags to do ...
> 
> Hans
> 
> Hans Bergsten wrote:
> >
> > Damian Fauth wrote:
> > >
> > > Hi,
> > >
> > > I recently upgraded from Tomcat 3.1m1 to 3.1beta1 and found that a
> > > number of my custom tags were broken by the new JspRunTimeLibrary class.
> > >
> > > The problem is the use of multiple 'setProperty()' methods for a single
> > > property in a custom tag.
> > >
> > > I have a number of such tags for rendering HTML form elements from beans
> > > and they can have both Enumeration and Hashtable objects assigned to the
> > > 'values' property - this is where the multiple 'setProperty()' methods
> > > come from - setValues(java.util.Enumeration) and
> > > setValues(java.util.Hashtable).
> > >
> > > So for example, using the bean:
> > >   <jsp:useBean id="stateHash" scope="application"
> > > class="java.util.Hashtable"/>
> > > the same tag can be used like this:
> > >   <form:select name="state" values="<%= stateHash.elements() %>"
> > > selected="Western Australia"/>
> > > or like this:
> > >   <form:select name="state" values="<%= stateHash %>" selected="WA"/>
> > >
> > > The getWriteMethod(Class beanClass, String prop) method in
> > > JspRuntimeLibrary.java steps through the beans properties looking for
> > > the matching property in order to get its write method, however
> > > PropertyDescriptor.getWriteMethod() is used to get the write method and
> > > which one it returns seems indeterminite, consequently I am getting an
> > > IllegalArgumentException
> > >
> > > My question: is my taglib consistent with the spec? Can a property of a
> > > bean have more than one 'set' method signature? If so, the following
> > > diff may be the basis for a patch - at least it works for my test cases
> > > (my custom tags) and for the taglib example packaged with tomcat.
> >
> > I also use beans with multiple setter methods with different signatures
> > for different types of values, and find it extremely powerful. I sure
> > hope that it's not against the spec (I can't see why) and that someone
> > can apply the patch you suggested (sorry, I just don't have the time).
> >
> > Hans
> > --
> > Hans Bergsten           hans@gefionsoftware.com
> > Gefion Software         http://www.gefionsoftware.com
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: general-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: general-help@jakarta.apache.org
> 
> --
> Hans Bergsten           hans@gefionsoftware.com
> Gefion Software         http://www.gefionsoftware.com
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: general-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: general-help@jakarta.apache.org

-- 
Damian Fauth                                
dfauth@access.fairfax.com.au
Senior Software Engineer                                     Ph 9282
3528
Fairfax Interactive Networks (f2) Ltd                       FAX 9282
2256
201 Sussex Street, Sydney, NSW, 2000, Australia     
http://www.f2.com.au

Re: JspRuntimeLibrary.java broke my taglib!

Posted by Hans Bergsten <ha...@gefionsoftware.com>.
Hi guys,

I responded to the message below on the general@jakarta.apache.org a while ago,
but since no one picked it up I decided to try to apply the patch myself today. 
But looking at this in more detail, I'm not sure if the behavior Damian
describes 
(present in a Tomcat 3.1m1, removed in 3.1beta1) is really valid according to 
the JSP and JavaBeans specs.

What it boils down to is whether a bean property can have multiple setter
methods, all with different types, or if there must only be one setter method
with a type matching the getter method (id any). It's extremely useful
(especially 
for custom actions), but from reading the JavaBeans spec and looking at the 
java.beans.PropertyDescriptor class I'm pretty sure it's "illegal".

A typical example of where this is useful is for a custom action with a
request-time attribute that can be set to many different types (e.g. int,
long, Date, etc.), such as the value to use in a JDBC PreparedStatement.

I would appreciate if someone can clarify if this is spec compliant or not.
If it is, I have a patch ready for Tomcat but a clarification may also be
needed in the JSP spec. If not, I have some rework on my SQL tags to do ...

Hans

Hans Bergsten wrote:
> 
> Damian Fauth wrote:
> >
> > Hi,
> >
> > I recently upgraded from Tomcat 3.1m1 to 3.1beta1 and found that a
> > number of my custom tags were broken by the new JspRunTimeLibrary class.
> >
> > The problem is the use of multiple 'setProperty()' methods for a single
> > property in a custom tag.
> >
> > I have a number of such tags for rendering HTML form elements from beans
> > and they can have both Enumeration and Hashtable objects assigned to the
> > 'values' property - this is where the multiple 'setProperty()' methods
> > come from - setValues(java.util.Enumeration) and
> > setValues(java.util.Hashtable).
> >
> > So for example, using the bean:
> >   <jsp:useBean id="stateHash" scope="application"
> > class="java.util.Hashtable"/>
> > the same tag can be used like this:
> >   <form:select name="state" values="<%= stateHash.elements() %>"
> > selected="Western Australia"/>
> > or like this:
> >   <form:select name="state" values="<%= stateHash %>" selected="WA"/>
> >
> > The getWriteMethod(Class beanClass, String prop) method in
> > JspRuntimeLibrary.java steps through the beans properties looking for
> > the matching property in order to get its write method, however
> > PropertyDescriptor.getWriteMethod() is used to get the write method and
> > which one it returns seems indeterminite, consequently I am getting an
> > IllegalArgumentException
> >
> > My question: is my taglib consistent with the spec? Can a property of a
> > bean have more than one 'set' method signature? If so, the following
> > diff may be the basis for a patch - at least it works for my test cases
> > (my custom tags) and for the taglib example packaged with tomcat.
> 
> I also use beans with multiple setter methods with different signatures
> for different types of values, and find it extremely powerful. I sure
> hope that it's not against the spec (I can't see why) and that someone
> can apply the patch you suggested (sorry, I just don't have the time).
> 
> Hans
> --
> Hans Bergsten           hans@gefionsoftware.com
> Gefion Software         http://www.gefionsoftware.com
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: general-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: general-help@jakarta.apache.org


-- 
Hans Bergsten		hans@gefionsoftware.com
Gefion Software		http://www.gefionsoftware.com

Re: JspRuntimeLibrary.java broke my taglib!

Posted by Hans Bergsten <ha...@gefionsoftware.com>.
Hi guys,

I responded to the message below on the general@jakarta.apache.org a while ago,
but since no one picked it up I decided to try to apply the patch myself today. 
But looking at this in more detail, I'm not sure if the behavior Damian
describes 
(present in a Tomcat 3.1m1, removed in 3.1beta1) is really valid according to 
the JSP and JavaBeans specs.

What it boils down to is whether a bean property can have multiple setter
methods, all with different types, or if there must only be one setter method
with a type matching the getter method (id any). It's extremely useful
(especially 
for custom actions), but from reading the JavaBeans spec and looking at the 
java.beans.PropertyDescriptor class I'm pretty sure it's "illegal".

A typical example of where this is useful is for a custom action with a
request-time attribute that can be set to many different types (e.g. int,
long, Date, etc.), such as the value to use in a JDBC PreparedStatement.

I would appreciate if someone can clarify if this is spec compliant or not.
If it is, I have a patch ready for Tomcat but a clarification may also be
needed in the JSP spec. If not, I have some rework on my SQL tags to do ...

Hans

Hans Bergsten wrote:
> 
> Damian Fauth wrote:
> >
> > Hi,
> >
> > I recently upgraded from Tomcat 3.1m1 to 3.1beta1 and found that a
> > number of my custom tags were broken by the new JspRunTimeLibrary class.
> >
> > The problem is the use of multiple 'setProperty()' methods for a single
> > property in a custom tag.
> >
> > I have a number of such tags for rendering HTML form elements from beans
> > and they can have both Enumeration and Hashtable objects assigned to the
> > 'values' property - this is where the multiple 'setProperty()' methods
> > come from - setValues(java.util.Enumeration) and
> > setValues(java.util.Hashtable).
> >
> > So for example, using the bean:
> >   <jsp:useBean id="stateHash" scope="application"
> > class="java.util.Hashtable"/>
> > the same tag can be used like this:
> >   <form:select name="state" values="<%= stateHash.elements() %>"
> > selected="Western Australia"/>
> > or like this:
> >   <form:select name="state" values="<%= stateHash %>" selected="WA"/>
> >
> > The getWriteMethod(Class beanClass, String prop) method in
> > JspRuntimeLibrary.java steps through the beans properties looking for
> > the matching property in order to get its write method, however
> > PropertyDescriptor.getWriteMethod() is used to get the write method and
> > which one it returns seems indeterminite, consequently I am getting an
> > IllegalArgumentException
> >
> > My question: is my taglib consistent with the spec? Can a property of a
> > bean have more than one 'set' method signature? If so, the following
> > diff may be the basis for a patch - at least it works for my test cases
> > (my custom tags) and for the taglib example packaged with tomcat.
> 
> I also use beans with multiple setter methods with different signatures
> for different types of values, and find it extremely powerful. I sure
> hope that it's not against the spec (I can't see why) and that someone
> can apply the patch you suggested (sorry, I just don't have the time).
> 
> Hans
> --
> Hans Bergsten           hans@gefionsoftware.com
> Gefion Software         http://www.gefionsoftware.com
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: general-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: general-help@jakarta.apache.org


-- 
Hans Bergsten		hans@gefionsoftware.com
Gefion Software		http://www.gefionsoftware.com

Re: JspRuntimeLibrary.java broke my taglib!

Posted by Hans Bergsten <ha...@gefionsoftware.com>.
Damian Fauth wrote:
> 
> Hi,
> 
> I recently upgraded from Tomcat 3.1m1 to 3.1beta1 and found that a
> number of my custom tags were broken by the new JspRunTimeLibrary class.
> 
> The problem is the use of multiple 'setProperty()' methods for a single
> property in a custom tag.
> 
> I have a number of such tags for rendering HTML form elements from beans
> and they can have both Enumeration and Hashtable objects assigned to the
> 'values' property - this is where the multiple 'setProperty()' methods
> come from - setValues(java.util.Enumeration) and
> setValues(java.util.Hashtable).
> 
> So for example, using the bean:
>   <jsp:useBean id="stateHash" scope="application"
> class="java.util.Hashtable"/>
> the same tag can be used like this:
>   <form:select name="state" values="<%= stateHash.elements() %>"
> selected="Western Australia"/>
> or like this:
>   <form:select name="state" values="<%= stateHash %>" selected="WA"/>
> 
> The getWriteMethod(Class beanClass, String prop) method in
> JspRuntimeLibrary.java steps through the beans properties looking for
> the matching property in order to get its write method, however
> PropertyDescriptor.getWriteMethod() is used to get the write method and
> which one it returns seems indeterminite, consequently I am getting an
> IllegalArgumentException
> 
> My question: is my taglib consistent with the spec? Can a property of a
> bean have more than one 'set' method signature? If so, the following
> diff may be the basis for a patch - at least it works for my test cases
> (my custom tags) and for the taglib example packaged with tomcat.

I also use beans with multiple setter methods with different signatures
for different types of values, and find it extremely powerful. I sure
hope that it's not against the spec (I can't see why) and that someone
can apply the patch you suggested (sorry, I just don't have the time).

Hans
-- 
Hans Bergsten		hans@gefionsoftware.com
Gefion Software		http://www.gefionsoftware.com