flowable/flowable-engine · warning

Using Joda-Time LocalDate has been deprecated and will be…

Error message

Using Joda-Time LocalDate has been deprecated and will be removed in a future version. Input variable {} from {} {} for decision table {} is a Joda-Time LocalDate. 

What it means

A deprecation WARN from ELExecutionContextBuilder.preProcessInputVariables: a Joda-Time org.joda.time.LocalDate was passed as an input variable when executing a decision table. Flowable transparently converts it to java.util.Date, but Joda-Time support will be removed in a future version.

Solutions

  1. Convert the variable to java.time.LocalDate (or java.util.Date) before invoking the decision.
  2. Search the calling code for org.joda.time imports and migrate to java.time (Joda is EOL).
  3. If conversion happens deep in a stack, add an explicit mapping layer over the input-variable map.

Example fix

// before
vars.put("birthDate", org.joda.time.LocalDate.now());
// after
vars.put("birthDate", java.time.LocalDate.now());
Defensive patterns

Strategy: type-guard

Validate before calling

if (vars.values().stream().anyMatch(v -> v instanceof org.joda.time.LocalDate)) { throw new IllegalArgumentException("Joda LocalDate not supported"); }

Type guard

boolean isJodaLocalDate(Object v) { return v instanceof org.joda.time.LocalDate; }

Prevention

When it happens

Trigger: Calling DecisionService.executeExecuteDecision... (e.g. dmnEngine.getDecisionService().executeWithSingleResult(...)) with a variables map containing a Joda-Time LocalDate value for a decision table input.

Common situations: Legacy codebases still on Joda-Time; code migrated from older Flowable/Activiti versions that used Joda types as process variables; third-party libraries returning Joda dates that are passed straight into DMN execution.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/46b24f43fdf65b8d. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/el/ELExecutionContextBuilder.java:123

        for (OutputClause outputClause : decisionTable.getOutputs()) {
            if (!inputVariables.containsKey(outputClause.getName()) || inputVariables.get(outputClause.getName()) == null) {
                if ("number".equals(outputClause.getTypeRef())) {
                    inputVariables.put(outputClause.getName(), 0D);
                } else if ("date".equals(outputClause.getTypeRef())) {
                    inputVariables.put(outputClause.getName(), new Date());
                } else {
                    inputVariables.put(outputClause.getName(), "");
                }
            }
        }

        // check if transformation is needed
        for (Map.Entry<String, Object> inputVariable : inputVariables.entrySet()) {
            String inputVariableName = inputVariable.getKey();
            try {
                Object inputVariableValue = inputVariable.getValue();
                if (inputVariableValue instanceof LocalDate) {
                    JodaDeprecationLogger.LOGGER.warn(
                            "Using Joda-Time LocalDate has been deprecated and will be removed in a future version."
                                    + " Input variable {} from {} {} for decision table {} is a Joda-Time LocalDate. ",
                            inputVariableName, executeDecisionInfo.getScopeType(), executeDecisionInfo.getInstanceId(), decisionTable.getId());
                    Date transformedDate = ((LocalDate) inputVariableValue).toDate();
                    inputVariables.put(inputVariableName, transformedDate);
                } else if (inputVariableValue instanceof java.time.LocalDate) {
                    Date transformedDate = Date.from(((java.time.LocalDate) inputVariableValue).atStartOfDay()
                            .atZone(ZoneId.systemDefault())
                            .toInstant());
                    inputVariables.put(inputVariableName, transformedDate);
                } else if (inputVariableValue instanceof Long || inputVariableValue instanceof Integer) {
                    BigInteger transformedNumber = new BigInteger(inputVariableValue.toString());
                    inputVariables.put(inputVariableName, transformedNumber);
                } else if (inputVariableValue instanceof Double ) {
                    BigDecimal transformedNumber = new BigDecimal((Double) inputVariableValue);
                    inputVariables.put(inputVariableName, transformedNumber);
                } else if (inputVariableValue instanceof Float) {
                    double doubleValue = Double.parseDouble(inputVariableValue.toString());

View on GitHub (pinned to d6d39ce1c6)