Uploaded image for project: 'Daffodil'
  1. Daffodil
  2. DAFFODIL-2839

Cast from xs:double/xs:float to xs:unsignedLong fails with ClassCastException error

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • None
    • 3.6.0
    • Front End
    • None

    Description

      The following schema parses a double and then has an expression to convert that double to an unsignedLong:

        <element name="root">
          <complexType>
            <sequence>
              <element name="double" type="xs:double" />
              <element name="ulong" type="xs:unsignedLong" dfdl:inputValueCalc="{ xs:unsignedLong(../double) }" />
            </sequence>
          </complexType>
        </element>
      

      This fails with the exception:

      rg.apache.daffodil.lib.exceptions.Abort: Invariant broken. Runtime.scala - Leaked exception: java.lang.ClassCastException: java.math.BigInteger cannot be cast to java.lang.Long
      java.lang.ClassCastException: java.math.BigInteger cannot be cast to java.lang.Long
      	at org.apache.daffodil.runtime1.infoset.DataValue$.getLong$extension(DataValue.scala:91)
      	at org.apache.daffodil.runtime1.dpath.LongToUnsignedLong$.computeValue(ConverterOps.scala:219)
      	at org.apache.daffodil.runtime1.dpath.LongToUnsignedLong$.computeValue(ConverterOps.scala:217)
      	at org.apache.daffodil.runtime1.dpath.Converter.run(DPathRuntime.scala:311)
      	at org.apache.daffodil.runtime1.dpath.CompiledDPath.run(DPathRuntime.scala:148)
      	at org.apache.daffodil.runtime1.dpath.CompiledDPath.runExpression(DPathRuntime.scala:73)
      	at org.apache.daffodil.runtime1.dpath.RuntimeExpressionDPath.evaluateExpression(DPath.scala:283)
      	at org.apache.daffodil.runtime1.dpath.RuntimeExpressionDPath.evaluateMaybe(DPath.scala:294)
      	at org.apache.daffodil.runtime1.dpath.RuntimeExpressionDPath.evaluate(DPath.scala:307)
      

      It seems like our expression compiler first converts the double to a long and then converts the long to an unsigned long, failing with the latter. Note that this is probably incorrect, since converting from a double to long first will limit the value to maxLong which it should not do.

      A sortof workaround is to change the expression to this:

      xs:unsignedLong(xs:long(../double))
      

      So we explicitly cast the double to a long, and then cast the long to the unsigned long. This still limits the range to maxLong, but does allow the conversion to succeed as expected as long as the double is in the range of 0 to maxLong.

      Attachments

        Activity

          People

            Unassigned Unassigned
            slawrence Steve Lawrence
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: