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
.
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;
}