Search code examples
javaspringspring-el

SpEL - disable short circuit evaluation


In my application, I have objects with several SpEL expressions that usually contains signatures of methods with boolean return type to invoke and logical operators. Before these objects are cached, I check the consistency of the expression by simply executing the parsed expression. When an exception is thrown, I set an appropriate flag inside the object to indicate that the expression is invalid to avoid further execution.

I am executing the expression on an EvaluationContext that implements all methods that are permitted to be a part of the expression. All these methods return false. I have come across a problem that involves a short circuit evaluation.

Given methodOne and methodTwo are the only permitted methods to invoke, this expression correctly sets the inconsistency flag

methodERROROne("arg") AND methodTwo("arg")

this one, however, does not because methodOne returns false, Spring uses short circuit evaluation and does not execute the remaining operands. This causes the expression to fail when it is executed on real EvaluationContext and the methodOne returns true

methodOne("arg") AND methodERRORTwo("arg")

Is there a way to disable short circuit evaluation is Spring expression language?


Solution

  • No; the OpAnd operator always short-circuits...

    @Override
    public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
        if (!getBooleanValue(state, getLeftOperand())) {
            // no need to evaluate right operand
            return BooleanTypedValue.FALSE;
        }
        return BooleanTypedValue.forValue(getBooleanValue(state, getRightOperand()));
    }
    

    ...there is no equivalent to Java's & operator.

    EDIT

    All these methods return false

    If they all return false can't you use "!(!m1() and !m2())" ?

    or even

    "!((!m1() or m1()) and (!m2() or m2()))"