javadroolsmvel

Mvel evaluation


Problem Statement: Say I have a expression (a + b + c), and I want to calculate its value and assign to some variable. Later I want use that variable value in some other logic. This is all done through MVEL. Issue is if anyone out of (a,b,c) is null, MVEL evaluates in a string format.

So to avoid this, I created my own function to pass each object and if it is null, make it zero.

Sample code below

public class MvelTest {

    public static void main(String[] args) {

        Map map = new HashMap();

        VariableResolverFactory functionFactory = new MapVariableResolverFactory(map);
        MVEL.eval("checkNullValue = def (x) { x == null ? 0 : x };", functionFactory);

        map.put("a", null);
        map.put("b", 1);
        map.put("c", 1);

        Serializable str = MVEL.compileExpression("( ( checkNullValue(a) + checkNullValue(b) + checkNullValue(c) ) > 2 ) ? d=2 : d=3");

        MVEL.executeExpression(str, map, functionFactory);
        System.out.println(map);
        System.out.println(map.get("d"));
    }
}

Output

{checkNullValue=function_prototype:null, b=1, c=1, a=null}
null

I am not able to get value of "d" here, and if I remove factory and null check function it behaves and I am able to get the value of "d". But I have to make it null safe for arithmetic operation, Since MVEL cannot handle this.

Also (null * 23), MVEL returns as false.


Solution

  • Issue got resolved, i was actually creating the static reference for VariableResolverFactory and was referring the same for every evaluation, i changed it to new instance for every execution and it worked.

     public VariableResolverFactory getMvelFactory(Map contextMap) {
            VariableResolverFactory functionFactory = new MapVariableResolverFactory(contextMap);
            MVEL.eval("checkNullValue = def (x) { x == null ? 0 : x };", functionFactory);
    
            return functionFactory;
        }