Uploaded image for project: 'camunda BPM'
  1. camunda BPM
  2. CAM-14684

ClassCastException in BeanELResolver

XMLWordPrintable

    • Icon: Bug Report Bug Report
    • Resolution: Fixed
    • Icon: L3 - Default L3 - Default
    • 7.18.0, 7.18.0-alpha5
    • 7.17.0
    • engine
    • None

      Environment (Required on creation):  Liberica Java 17

      Description (Required on creation; please attach any relevant screenshots, stacktraces, log files, etc. to the ticket):

       

      We have a conditionExpression:

      #{status == "approve" && total.compareTo(0) >= 0}

      balance is a BigDecimal. This seemed to work ok, but suddenly we had problems when switching JVMs from Eclipse Temurin to Liberica.

      rg.camunda.bpm.engine.ProcessEngineException: Error while evaluating expression: #{status == "approve" && total.compareTo(0) >= 0}. Cause: java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.math.BigDecimal (java.lang.Long and java.math.BigDecimal are in module java.base of loader 'bootstrap')

      We eventually traced this down to:

      BeanELResolver.findMethod() is called with no types defined, so it simply calls BigDecimal.getClass().getMethods() and iterates looking for `compareTo`.

      Unfortunately, in our new JVM base container, the ordering of the methods is random:

      This order works fine:
      public int java.math.BigDecimal.compareTo(java.math.BigDecimal)
      public int java.math.BigDecimal.compareTo(java.lang.Object)

      However, sometimes the order returned is reversed and `compareTo(java.lang.Object)` is first. When that happens, TypeConverterImpl.coerceToType is called with a Long value and a type of Object.

      It falls through to type.isInstance(value), which of course returns true, passing the original Long back without conversion.

      This then throws an InvocationTargetException caused by the ClassCastException trying to pass a Long to a method that requires a BigDecimal.

      Although I was slightly tempted to blame our new choice of JVM, the Javadoc for getMethods() is clear: "The elements in the returned array are not sorted and are not in any particular order."

      Steps to reproduce (Required on creation):

      Running on Liberica JVM (and presumably others), create an expression that would require a coercion as above.

      Observed Behavior (Required on creation):

      Long is cast to BigDecimal, which fails.

      Expected behavior (Required on creation):

      Long 0 is coerced to BigDecimal.

      Root Cause (Required on prioritization):

      Solution Ideas (Optional):

       

      I'm not familiar enough with this code to know if the problem is that `findMethod` is called without any types, or if the fall-through call to `getMethods()` needs to be more selective, or even multi-pass.

      Hints (optional):

        This is the controller panel for Smart Panels app

              tassilo.weidner Tassilo Weidner
              cott cott
              Tassilo Weidner Tassilo Weidner
              Miklas Boskamp Miklas Boskamp
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved: