Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.6
-
None
-
None
-
Operating System: other
Platform: All
-
34766
Description
Hi all!
First, thank you for creating such great software as the whole Jakarta project.
I have a very specific problem regarding Commons Digester, in particular
CallMethodRule
The javadoc states:
--------------
- If a CallMethodRule is expecting more than one parameter,
- then it is always invoked, regardless of whether the parameters were
- available or not (missing parameters are passed as null values).</p>
---------------
Please note the last phrase: "missing parameters are passed as null values".
This is an excerpt from the logs of my application (client class names had been
cut out):
-----------------
DEBUG main org.apache.commons.digester.Digester - Fire end() for
CallMethodRule[methodName=setUtenzeBT, paramCount=5,
paramTypes=
]
DEBUG main org.apache.commons.digester.Digester - Popping params
DEBUG main org.apache.commons.digester.Digester - [CallMethodRule](0)null
DEBUG main org.apache.commons.digester.Digester - [CallMethodRule](1)null
DEBUG main org.apache.commons.digester.Digester - [CallMethodRule](2)null
DEBUG main org.apache.commons.digester.Digester - [CallMethodRule](3)null
DEBUG main org.apache.commons.digester.Digester - [CallMethodRule](4)null
DEBUG main org.apache.commons.beanutils.ConvertUtils - Convert string 'null' to
class 'java.lang.Float'
DEBUG main org.apache.commons.beanutils.ConvertUtils - Using converter
org.apache.commons.beanutils.converters.FloatConverter@288051
DEBUG main org.apache.commons.beanutils.ConvertUtils - Convert string 'null' to
class 'java.lang.Integer'
DEBUG main org.apache.commons.beanutils.ConvertUtils - Using converter
org.apache.commons.beanutils.converters.IntegerConverter@10045eb
DEBUG main org.apache.commons.beanutils.ConvertUtils - Convert string 'null' to
class 'java.lang.Float'
DEBUG main org.apache.commons.beanutils.ConvertUtils - Using converter
org.apache.commons.beanutils.converters.FloatConverter@288051
DEBUG main org.apache.commons.beanutils.ConvertUtils - Convert string 'null' to
class 'java.lang.Integer'
DEBUG main org.apache.commons.beanutils.ConvertUtils - Using converter
org.apache.commons.beanutils.converters.IntegerConverter@10045eb
DEBUG main org.apache.commons.beanutils.ConvertUtils - Convert string 'null' to
class 'java.lang.Float'
DEBUG main org.apache.commons.beanutils.ConvertUtils - Using converter
org.apache.commons.beanutils.converters.FloatConverter@288051
DEBUG main org.apache.commons.digester.Digester - [CallMethodRule]
Call
it.setUtenzeBT(0.0/java.lang.Float,0/java.lang.Integer,0.0/java.lang.Float,0/java.lang.Integer,0.0/java.lang.Float)
DEBUG main org.apache.commons.beanutils.MethodUtils - Matching name=setUtenzeBT
on class it
DEBUG main org.apache.commons.beanutils.MethodUtils - Found straight match:
public void
it.setUtenzeBT(java.lang.Float,java.lang.Integer,java.lang.Float,java.lang.Integer,java.lang.Float)
throws it.DataValidationException
DEBUG main org.apache.commons.beanutils.MethodUtils - isPublic:true
DEBUG main org.apache.commons.digester.Digester - Fire end() for
SetNextRule[methodName=add, paramType=java.lang.Object]
-----------------
If you look at the first lines, you see the five "[CallMethodRule](0)null"
entries. That's correct, because the data passed in hasn't got the inner element
needed for the parameter.
But, after that, instead of calling it.setUtenzeBT(null, null, null, null,
null), Digester calls
it.setUtenzeBT(0.0/java.lang.Float,0/java.lang.Integer,0.0/java.lang.Float,
0/java.lang.Integer,0.0/java.lang.Float), that is with zeros, having converted
the nulls to Strings before, and then to Floats.
I think the problem lies around here:
From:
/jakarta/commons/proper/digester/tags/DIGESTER_1_6/src/java/org/apache/commons/digester/CallMethodRule.java
Revision: 132717
-----------------
// Construct the parameter values array we will need
// We only do the conversion if the param value is a String and
// the specified paramType is not String.
Object paramValues[] = new Object[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
// convert nulls and convert stringy parameters
// for non-stringy param types
if(
parameters[i] == null ||
(parameters[i] instanceof String &&
!String.class.isAssignableFrom(paramTypes[i])))
else
{ paramValues[i] = parameters[i]; } }
-----------------
I don't think 'parameters[i] == null' should be ||'ed with the other condition.
It should call convert only when a real object gets passed. I could be wrong,
however. It's the first time I glance at Commons' source code, and even if it is
extra clear, I may miss something.
However, I think the logged behaviour doesn't match what advertised in the
javadocs, and I need the latter one.
I'v searched BugZilla without finding anything similar to this, so I posted this
bug.
If more info/test data is needed, I'll prepare it (that means i'll have to
delete the details I can't make public).
Thanks in advance to anyone who can help me.
Michele Mauro