3

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?

Kishan Khatanhar
  • 63
  • 1
  • 1
  • 9

1 Answers1

6

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.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • I would do that but the expression will not always be the same. It will probably change in the future. And I don't want to keep changing the Java code modifying the map every time the expression changes. Actually, I am storing the expression in a database table and evaluating the expression in Java. So the Java code doesn't change at all. – Kishan Khatanhar Oct 27 '19 at 14:09
  • Thanks a lot, Arvind. I created a dynamic map and passed it to eval method. – Kishan Khatanhar Oct 28 '19 at 08:00