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
- Convert the variable to java.time.LocalDate (or java.util.Date) before invoking the decision.
- Search the calling code for org.joda.time imports and migrate to java.time (Joda is EOL).
- 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
- Ban org.joda.time imports via Checkstyle/ArchUnit
- Use java.time.LocalDate for all DMN input variables
- Add a mapping layer over decision input maps
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
- Using Joda-Time LocalDate has been deprecated and will be…
- Using Joda-Time LocalDate has been deprecated and will be…
- date object cannot be empty
- Using Joda-Time DateTime has been deprecated and will be…
- Using Joda-Time DateTime has been deprecated and will be…
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)