Commons Digester
  1. Commons Digester
  2. DIGESTER-3

[digester] CallMethodRule doesn't call with null parameters, String-ifies them first.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.6
    • Fix Version/s: None
    • Labels:
      None
    • Environment:

      Operating System: other
      Platform: All

      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=

      {java.lang.Float, java.lang.Integer, java.lang.Float, java.lang.Integer, java.lang.Float}

      ]
      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]

      {rl/i/ria}

      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])))

      { paramValues[i] = ConvertUtils.convert((String) parameters[i], 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

        Activity

        Michele Mauro created issue -
        Henri Yandell made changes -
        Field Original Value New Value
        issue.field.bugzillaimportkey 34766 12342227
        Henri Yandell made changes -
        Key COM-2075 DIGESTER-3
        Project Commons [ 12310458 ] Commons Digester [ 12310471 ]
        Component/s Digester [ 12311111 ]
        Assignee Jakarta Commons Developers Mailing List [ commons-dev@jakarta.apache.org ]
        Affects Version/s 1.6 Final [ 12311666 ]
        Henri Yandell made changes -
        Affects Version/s 1.6 Final [ 12311712 ]
        Henri Yandell made changes -
        Status Resolved [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            Unassigned
            Reporter:
            Michele Mauro
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development