3

I'm using Mvel API mvel2 2.4.4.Final to write some rule based logic's in my java web application.

I have list of Mvel Expressions which should be compiled before I use them in real operations to avoid any invalid expression problems while client requests.


Mvel Expression

This is one of my Mvel Expression which I want to be compiled

a.totalAmount <= 30 && a.currency == "981" && a.merchantId == testMerchant


Transaction Object

This class contains all properties which is used in Mvel expressions

public class Transaction {
  private String merchantId;
  private double totalAmount;
  private String currency;  
  ...
}

Expression Validation Code

public static void compile(List<Rule> ruleList)  {   
    ruleList.forEach(rule -> {
      ParserContext context = new ParserContext();
      context.setStrictTypeEnforcement(true);
      context.addInput("a", Transaction.class);
      MVEL.compileExpression(rule.getMvelExpression(), context);
      }
    });
  }

The validation code above does not catch any error when compiling the Mvel expression and compilation ends successfully, but when program tries to compare transaction object values to the Mvel expression values using this code bellow, it throws the org.mvel2.PropertyAccessException


Evaluation Code

  public void eval(Rule rule, Transaction tran) {
    Map<String, Object> inputContext = new HashMap<>();
    inputContext.put("a", tran);
    MVEL.eval(rule.getMvelExpression(), inputContext);
  }

Exception details

[Near : {... t <= 30 && a.currency == "981" && a.merchantId == testMerchant ....}]
                                                               ^
[Line: 1, Column: 63] }}} 
org.mvel2.PropertyAccessException: [Error: unresolvable property or identifier: testMerchant]
[Near : {... t <= 30 && a.currency == "981" && a.merchantId == testMerchant ....}]
                                                               ^
[Line: 1, Column: 63]
    at org.mvel2.PropertyAccessor.getBeanProperty(PropertyAccessor.java:676) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.PropertyAccessor.getNormal(PropertyAccessor.java:178) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.PropertyAccessor.get(PropertyAccessor.java:145) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.PropertyAccessor.get(PropertyAccessor.java:125) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.ast.ASTNode.getReducedValue(ASTNode.java:187) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.MVELInterpretedRuntime.parseAndExecuteInterpreted(MVELInterpretedRuntime.java:145) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.MVELInterpretedRuntime.parse(MVELInterpretedRuntime.java:47) ~[mvel2-2.4.4.Final.jar:?]
    at org.mvel2.MVEL.eval(MVEL.java:165) ~[mvel2-2.4.4.Final.jar:?]

As you can see in Exception, the problem is that the value of a.merchantId in Mvel Expression is not in quotes, if I add quotes like this a.merchantId == "testMerchant" then everything works fine.

But due to the documentation of Mvel API:

enter image description here enter image description here


Question

  1. Why MVEL.eval(rule.getMvelExpression(), inputContext); code throws exception if MVEL automatically assigns the correct type to a.merchantId by Value Coercion concept?
  2. Why the compiler does not catches this exception, and how to Coercion Mvel to catch?
  3. Why the org.mvel2.PropertyAccessException: [Error: unresolvable property or identifier: testMerchant] exception is thrown when the problem is in quotes?
jiboOne
  • 541
  • 5
  • 18

0 Answers0