javamvel

How to use variables inside an MVEL expression?


I have pre-defined variables in my Java code which I want to use inside an MVEL expression. I don't want to pass a context.

String Col1 = "C";
String Col2 = "D";
String expression = "Col1 == 'C' && Col2 == 'D'";

Boolean result = (Boolean) MVEL.eval(expression);

How do I read the variable values and evaluate the expression to true or false?


Solution

  • You need to add your variables, col1 and col2 to a context object and then pass this object to MVEL.eval. Given below is the working example:

    import java.util.HashMap;
    import java.util.Map;
    
    import org.mvel2.MVEL;
    
    public class Test {
        public static void main(String[] args) {
            Map<String, Object> context = new HashMap<String, Object>();
    
            String col1 = "C";
            String col2 = "D";
    
            context.put("col1", col1);
            context.put("col2", col2);
    
            String expression = "col1 == 'C' && col2 == 'D'";
            Boolean result = (Boolean) MVEL.eval(expression,context);
            System.out.println(result);//true
    
            expression = "col1 == 'E' && col2 == 'D'";
            result = (Boolean) MVEL.eval(expression,context);
            System.out.println(result);//false
        }
    }
    

    Feel free to let me know in case you have any further doubt.

    Update: the following update is to explain why you need the context object (you have mentioned in your comment that you do not want to add your variables to a context object).

    If you look into the documentation at https://github.com/mvel/mvel/blob/master/src/main/java/org/mvel2/MVEL.java, you will be tempted to use the following method:

    public static Object eval(String expression) {
        return new MVELInterpretedRuntime(expression, new ImmutableDefaultFactory()).parse();
    }
    

    However, the following piece of code will fail to compile:

    String col1 = "C";
    String col2 = "D";
    String expression = "col1 == 'C' && col2 == 'D'";
    System.out.println(new MVELInterpretedRuntime(expression, new ImmutableDefaultFactory()).parse());
    

    The reason for this is, the visibility of the following constructor is not public.

    MVELInterpretedRuntime(String expression, VariableResolverFactory resolverFactory) {
        setExpression(expression);
        this.variableFactory = resolverFactory;
    }
    

    So, you need to populate a context object in your client program and pass this object, along with the expression, to the program/method evaluating MVEL expression. In my program, it is the main method where I am populating the context object as well as evaluating the MVEL expression.