Giter Club home page Giter Club logo

mvel's Introduction

MVEL

MVFLEX Expression Language (MVEL) is a hybrid dynamic/statically typed, embeddable Expression Language and runtime for the Java Platform.

Document

http://mvel.documentnode.com/

How to build

git clone https://github.com/mvel/mvel.git
cd mvel
mvn clean install

mvel's People

Contributors

barfoo4711 avatar deaddowney avatar dependabot[bot] avatar dfeist avatar etirelli avatar ge0ffrey avatar johnlbergqvist avatar kedzie avatar kudrevatykh avatar lkt avatar lucamolteni avatar machaval avatar malcolmodd avatar mariofusco avatar maxdamantus avatar mdproctor avatar mikebrock avatar mkostrze avatar mmelko avatar natanik avatar oscerd avatar qxo avatar raipc avatar ruoyangryan avatar srwfan avatar tarilabs avatar tkobayas avatar viswaramamoorthy avatar wangnk avatar x1aofang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mvel's Issues

Cannot compile template on JDK9

Seen on JDK9-ea137

Caused by: java.lang.ExceptionInInitializerError
    at org.mvel2.templates.TemplateCompiler.captureOrbToken(TemplateCompiler.java:305)
    at org.mvel2.templates.TemplateCompiler.compileFrom(TemplateCompiler.java:114)
    at org.mvel2.templates.TemplateCompiler.compile(TemplateCompiler.java:82)
    at org.mvel2.templates.TemplateCompiler.compileTemplate(TemplateCompiler.java:360)
    at org.apache.camel.component.mvel.MvelEndpoint.onExchange(MvelEndpoint.java:115)
    at org.apache.camel.impl.ProcessorEndpoint$1.process(ProcessorEndpoint.java:71)
    at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
    ... 163 more
Caused by: java.lang.NumberFormatException: For input string: "9-e"
    at jdk.internal.math.FloatingDecimal.readJavaFormatString(java.base@9-ea/FloatingDecimal.java:2054)
    at jdk.internal.math.FloatingDecimal.parseDouble(java.base@9-ea/FloatingDecimal.java:110)
    at java.lang.Double.parseDouble(java.base@9-ea/Double.java:539)
    at org.mvel2.util.ParseTools.<clinit>(ParseTools.java:84)
    ... 170 more

CrossRef: wildfly-extras/wildfly-camel#1340

CompiledExpression execution fails when evaluating with null value followed by non null value

Below code snippet reproduces null pointer exception when compiled expression executed with null values followed by non-values.

MvelCompileExpNullSafeTest.zip

Tested with v2.4.0-Final

Code Snippet

    String expression = "((parentGroup != null) && ($.?child.firstName in parentGroup.parentList if  $.?child.firstName != null).size() > 0)";
    ExpressionCompiler compiler = new ExpressionCompiler(expression, true);
    CompiledExpression compiledExpression = compiler.compile();
   
	ParentGroup pGroup = new ParentGroup();
	List<Parent> list = new ArrayList<Parent>();
	Parent parent = new Parent();
	parent.setChild(null);
	list.add(parent);
	pGroup.setParentList(list);

	Boolean result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
	assert result == false;

	Child child = new Child();
	child.setFirstName("viswa");

	pGroup = new ParentGroup();
	list = new ArrayList<Parent>();
	parent = new Parent();
	parent.setChild(child);
	list.add(parent);
	child = new Child();
	child.setFirstName(null);
	parent = new Parent();
	parent.setChild(child);
	list.add(parent);
	pGroup.setParentList(list);

	result = (Boolean)MVEL.executeExpression(compiledExpression, Collections.<String, Object>singletonMap("parentGroup", pGroup));
	assert result == true;

Complete test code attached

Exception seen
java.lang.RuntimeException: cannot invoke getter: getChild (see trace)
at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:70)
at org.mvel2.optimizers.impl.refl.nodes.VariableAccessor.getValue(VariableAccessor.java:37)
at org.mvel2.optimizers.dynamic.DynamicGetAccessor.getValue(DynamicGetAccessor.java:78)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108)
at org.mvel2.ast.BinaryOperation.getReducedValueAccelerated(BinaryOperation.java:117)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.ast.Fold.getReducedValueAccelerated(Fold.java:91)
at org.mvel2.ast.Union.getReducedValueAccelerated(Union.java:39)
at org.mvel2.ast.BinaryOperation.getReducedValueAccelerated(BinaryOperation.java:117)
at org.mvel2.ast.And.getReducedValueAccelerated(And.java:34)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
at org.mvel2.MVEL.executeExpression(MVEL.java:968)
at test.mvel.MvelCompileExpNullSafeTest.testMvelCompileNullSafe(MvelCompileExpNullSafeTest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NullPointerException
at org.mvel2.optimizers.impl.refl.nodes.NullSafe$1.getValue(NullSafe.java:39)
at org.mvel2.optimizers.impl.refl.nodes.NullSafe.getValue(NullSafe.java:54)
at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:40)
... 39 more

null is converted to string

I found if I add a integer to a variable which value is null, the variable will become to a string like "nullxxx". Is this a normal behavior?

For example, below is a experiment in mvel shell: when I added integer 2 to a null variable aa, the result was a string "null2".
image

Null Safe Operation Problem

I have a list of items and try to find the items that meet the following expression :
($ in objectList if (($.?office.no == V1) && ($.?title.no == V2 || $.?title.no == V3 || $.?title.no == V4 || $.?title.no == V5)) || (($.?office.no == V6) || ($.?unit.no == V7) && ($.?title.no == V8)))

I think the notation is right, but despite the null safe notation I still get the following exception related with "unit". It seems to be a bug, any help or suggestion ?

java.lang.RuntimeException: cannot invoke getter: getUnit (see trace) java.lang.NullPointerException

Thank you.

Compilation error when use Java Lambda Functions has parameter

Compile error occurs when using lambda function as in the example below. The funcion map(entry -> entry.getKey()) cause the error. Replacing function to map(Entry::Key) causes the same error.

Expression with error:

values = ["A":1, "B":1, "C":1, "D":1, "E":1, "F":1, "G":1, "H":1];
firstValues = values.entrySet().stream().limit(5).map(entry -> entry.getKey()).collect(java.util.stream.Collectors.toList());
return firstValues;

Error:

java.lang.RuntimeException: Malformed expression
	at org.mvel2.util.ASTBinaryTree.getReturnType(ASTBinaryTree.java:35)
	at org.mvel2.util.ASTBinaryTree.getReturnType(ASTBinaryTree.java:36)
	at org.mvel2.util.CompilerTools.getReturnType(CompilerTools.java:358)
	at org.mvel2.compiler.ExpressionCompiler._compile(ExpressionCompiler.java:284)
	at org.mvel2.compiler.ExpressionCompiler.compile(ExpressionCompiler.java:52)
	at org.mvel2.MVEL.analyze(MVEL.java:680)
	at org.mvel2.compiler.PropertyVerifier.getMethod(PropertyVerifier.java:526)
	at org.mvel2.compiler.PropertyVerifier.analyze(PropertyVerifier.java:120)
	at org.mvel2.compiler.ExpressionCompiler.verify(ExpressionCompiler.java:373)
	at org.mvel2.compiler.ExpressionCompiler._compile(ExpressionCompiler.java:266)
	at org.mvel2.util.ParseTools.subCompileExpression(ParseTools.java:2059)
	at org.mvel2.ast.AssignmentNode.<init>(AssignmentNode.java:69)
	at org.mvel2.compiler.AbstractParser.nextToken(AbstractParser.java:863)
	at org.mvel2.compiler.ExpressionCompiler._compile(ExpressionCompiler.java:111)
	at org.mvel2.compiler.ExpressionCompiler.compile(ExpressionCompiler.java:52)
	at org.mvel2.MVEL.compileExpression(MVEL.java:810)

Compilation Exception - ArrayIndexOutOfBoundsException with a FOR in the IF

Hi,

I use MVEL for a few years and now I found a problem when a FOR loop it's inside IF.

Example of expression with cause the exception:

List list1 = [1,2,3,4,5,6,7,8];
List list2 = new ArrayList();

if (list1 != null) {
   for(int item : list1) {
      list2.add(item);
   }
}

The expression without IF, work's fine:

List list1 = [1,2,3,4,5,6,7,8];
List list2 = new ArrayList();

for(int item : list1) {
   list2.add(item);
}

Log msg:

org.mvel2.CompileException: [Error: unexpected end of statement]
[Near : {... ist1) { ....}]
                    ^
[Line: 10, Column: 13]
        at org.mvel2.compiler.AbstractParser.nextToken(AbstractParser.java:1292)
at org.mvel2.compiler.AbstractParser.nextToken(AbstractParser.java:1292)
        at org.mvel2.compiler.ExpressionCompiler._compile(ExpressionCompiler.java:111)
        at org.mvel2.compiler.ExpressionCompiler.compile(ExpressionCompiler.java:52)
        at org.mvel2.MVEL.compileExpression(MVEL.java:810)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 168
        at org.mvel2.compiler.AbstractParser.ifThenElseBlockContinues(AbstractParser.java:1787)
        at org.mvel2.compiler.AbstractParser.captureCodeBlock(AbstractParser.java:1604)
        at org.mvel2.compiler.AbstractParser.nextToken(AbstractParser.java:433)
        ... 47 common frames omitted

I tested in versions 2.2.7 and 2.3.1 and the same problem occurred

is this an active project

I want to use mvel in my project , is this an active project ? or is there an alternative that you might recommend

[Question] Is MVEL evaluation case sensitive ?

I am using MVEL for evaluate java object.

Working:
print org.mvel2.MVEL.eval("?getWrapIn.getAccountNumber", request) ===> "12345"

Not Working:
print org.mvel2.MVEL.eval("?getwrapin.getaccountnumber", request) ===> null

Is there any workaround to make it is behaving same way irrespective of cases.

PropertyAccessException on second run of compiled expression with null safe operator and whitespace

Hi, we've detected a problem when reusing a compiled expression involving the null safe operator and whitespace or parenthesis:

If the expression is like "?bean.?value == \"a\"" it's evaluation and reevaluation is ok.

But if the expression is like " ?bean.?value == \"a\"" or "(?bean.?value == \"a\")", the first evaluation succeeeds, but the second one fails with a PropertyAccessException on a trimmed-down property (valu in this case:

[Error: could not access: valu; in class: org.mvel2.tests.core.NullSafeTest$Reg1]
[Near : {... (?bean.?value) ....}]
                    ^
[Line: 1, Column: 8]
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:706)
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:360)
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:163)
	at org.mvel2.optimizers.impl.refl.nodes.NullSafe.getValue(NullSafe.java:27)
	at org.mvel2.optimizers.impl.refl.nodes.VariableAccessor.getValue(VariableAccessor.java:37)
	at org.mvel2.optimizers.dynamic.DynamicGetAccessor.getValue(DynamicGetAccessor.java:78)
	at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108)
	at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
	at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
	at org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
	at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
	at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
	at org.mvel2.MVEL.executeExpression(MVEL.java:968)

Funnily enough, adding more whitespace or parenthesis prepended to the sentence seems to trim down even more the property access. Expressions like " ?bean.?value == \"a\"" or "((?bean.?value == \"a\"))", fail with an incorrect access to val property:

[Error: could not access: val; in class: org.mvel2.tests.core.NullSafeTest$Reg1]
[Near : {... ((?bean.?value)) ....}]
                     ^
[Line: 1, Column: 9]
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:706)
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:360)
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:163)
	at org.mvel2.optimizers.impl.refl.nodes.NullSafe.getValue(NullSafe.java:27)
	at org.mvel2.optimizers.impl.refl.nodes.VariableAccessor.getValue(VariableAccessor.java:37)
	at org.mvel2.optimizers.dynamic.DynamicGetAccessor.getValue(DynamicGetAccessor.java:78)
	at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108)
	at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
	at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
	at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
	at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
	at org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
	at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
	at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
	at org.mvel2.MVEL.executeExpression(MVEL.java:968)

I attach a testcase reproducing the issue:
NullSafeTest.zip

Issue #115 could be related. This test case seems simpler, though.

[Question] Is there a way to undef a defined function?

Now I use MVEL lots, all using a Map<String, Object>(varMap) to hold all variables and definitions together while executing very long expressions sequentially. In this way, it's very convenient to get a variable outside by calling varMap.get("variableName"), or add a variable outside by calling varMap.put("variableName", variableValue).

I wonder is there a way to undef a defined function in MVEL-expression, or override it. All I want is to build a nice structure to expressions which will be compiled and executed sequentially. I do not want to use VariableResolverFactory-chain to do this, because get a variable from this factory is not so convenient(null check is fix-coded in java now).

MVEL rejects operations on classes that implement Comparable-Interface

In MVEL 1.3.1 it was possible to use operators like '<' or '>' to compare objects of different types where both of the types implement the java.lang.Comparable-Interface.

With MVEL 2 these possibilities are implemented in org.mvel2.math.MathProcessor.java (e.g. in case GTHAN) but are rejected by org.mvel2.ast.BinaryOperation.java and org.mvel2.util.CompatibilityStrategy.java.

I have tested it by overwritting both classes and adding the following code to ensure that code execution on comparable classes is allowed:

In org.mvel2.ast.BinaryOperation.java extend the method areCompatible with the following condition:
Comparable.class.isAssignableFrom(leftClass) && Comparable.class.isAssignableFrom(rightClass)

In org.mvel2.util.CompatibilityStrategy.java extend the DefaultCompatibilityEvaluator with the method areEqualityCompatible with the following code:
if (Comparable.class.isAssignableFrom(c1) && Comparable.class.isAssignableFrom(c2)) return true

Could you add this in future releases?

Mvel error occurs randomly while executing rule engine

ASMAccessorImpl_1764486741458637539500.getValue(Ljava/lang/Object;Ljava/lang/Object;Lorg/mvel2/integration/VariableResolverFactory;)Ljava/lang/Object; @35: invokeinterface
Reason:
Type 'java/lang/Object' (current frame, stack[1]) is not assignable to integer
Current Frame:
bci: @35
flags: { }
locals: { 'ASMAccessorImpl_1764486741458637539500', 'java/lang/Object', 'java/lang/Object', 'org/mvel2/integration/VariableResolverFactory' }
stack: { 'java/util/List', 'java/lang/Object' }
Bytecode:
0x0000000: 2d12 0eb9 0014 0200 b900 1901 00c0 001b
0x0000010: b600 1fc0 0021 2d12 23b9 0014 0200 b900
0x0000020: 1901 00b9 0027 0200 c000 29b6 002d b0

at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructor0(Class.java:3075)
at java.lang.Class.newInstance(Class.java:412)
at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer._initializeAccessor(ASMAccessorOptimizer.java:723)
at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.compileAccessor(ASMAccessorOptimizer.java:857)
at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.optimizeAccessor(ASMAccessorOptimizer.java:245)
at org.mvel2.optimizers.dynamic.DynamicGetAccessor.optimize(DynamicGetAccessor.java:96)
at org.mvel2.optimizers.dynamic.DynamicGetAccessor.getValue(DynamicGetAccessor.java:66)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108)
at org.mvel2.ast.BinaryOperation.getReducedValueAccelerated(BinaryOperation.java:117)
at org.mvel2.ast.Or.getReducedValueAccelerated(Or.java:34)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
at org.mvel2.ast.And.getReducedValueAccelerated(And.java:34)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
at org.mvel2.ast.Or.getReducedValueAccelerated(Or.java:34)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
at org.mvel2.ast.And.getReducedValueAccelerated(And.java:34)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.ast.IfNode.getReducedValueAccelerated(IfNode.java:73)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:86)
at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:106)
at org.mvel2.ast.ForNode.getReducedValueAccelerated(ForNode.java:67)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:86)
at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:106)
at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:86)
at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:106)
at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.ast.Substatement.getReducedValueAccelerated(Substatement.java:44)
at org.mvel2.ast.And.getReducedValueAccelerated(And.java:34)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:42)
at org.mvel2.MVEL.executeExpression(MVEL.java:969)
at ch.maxant.rules.Engine.getMatchingRules(Engine.java:364)
at ch.maxant.rules.Engine.getMatchingRules(Engine.java:336)
at com.cointribe.details.services.CibilReportServices.checkCibilScoring(CibilReportServices.java:389)
at com.cointribe.bank.intgrations.axis.AxisService.processApplication(AxisService.java:144)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)

New lines not generated in included templates

We are using mvel2 in lz4-java to generate Java source code from templates. Until mvel2-2.3.2 it worked fine, but I noticed that in mvel2-2.4.0, no new line was output from templates included by @include. Even if a source template contains new lines, everything is in a single line in the output. Is this intended behavior?

Maps' and collections' generic type is not resolved when using bracket notation

Consider the following snippet:

value = map['key'].trim()
sameValue = map.get('key').trim()

If map is a subclass of Map<String, String> with overridden method get, compilation of the first expression will fail in strict mode, and the second one will succeed. Is there a possibility to infer String in the first expression, too?

Does MVEL automatically import java.lang in compileExpression?

Hi,

I'm doing a project using MVEL and Apache Spark, in which I saw the following behavior for expression "java.lang.Math.log(1.0f)":

  • If I do MVEL.eval(exp, ctxObj), it is correctly evaluated
  • if I do

MVEL.executeExpression(MVEL.compileExpression(exp, new ParserContext(new ParserConfiguration())), ctxObj)

It gives me a NullPointerException saying not able to find java.lang.Math.log:

[Near : {... java.lang.Math.log(1.0f}]
             ^
[Line: 1, Column: 1]
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:450)
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:163)
	at org.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
	at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
	at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:42)
	at org.mvel2.MVEL.executeExpression(MVEL.java:953)
	at com.linkedin.frameproto.offline.client.FrameDebugClient$$anonfun$tryGetWithMvel$1$$anonfun$apply$10$$anonfun$apply$11.apply(FrameDebugClient.scala:201)
	at scala.util.Try$.apply(Try.scala:161)
	... 26 more
Caused by: java.lang.NullPointerException
	at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:383)
	... 33 more

Do MVEL.eval and MVEL.compileExpression behave differently in terms of referring to java internal classes? Do I always need to explicity import java.lang when I compile an expression?

Thanks!

[Improvement] Expression caching strategy for AbstractOptimizer class

While calling tryStaticAccess method in AbstractOptimizer class with the same expressions multiple times, which cannot be resolved, it would increase the performance if unresolved expressions would be cached somewhere and there wouldn't be a need to repeatedly resolve them over and over again.

At the moment we are modified this class in a quite simple and straightforward way. We are saving those expression in a map and if a new one is already on it, we exit the method immediately (Please find the patch file attached for more details). Maybe there is another (better) way of doing this?

mvel222Final.zip

not contains operator

I have a mvel expression that requires the not contains operator. The expression is

input.shipment.sHIPMENTDESC not contains 'GINGER'

I get a mvel compilation error when i try the above in a junit test. The stacktrace is as below

at org.mvel2.compiler.AbstractParser.procTypedNode(AbstractParser.java:1505)
at org.mvel2.compiler.AbstractParser.createPropertyToken(AbstractParser.java:1405)
at org.mvel2.compiler.AbstractParser.nextToken(AbstractParser.java:893)
at org.mvel2.compiler.ExpressionCompiler._compile(ExpressionCompiler.java:126)
at org.mvel2.compiler.ExpressionCompiler.compile(ExpressionCompiler.java:67)
at org.mvel2.MVEL.compileExpression(MVEL.java:810)
at org.mvel2.MVEL.compileExpression(MVEL.java:819)
at org.mvel2.MVEL.compileExpression(MVEL.java:723)

What is the solution to the problem? Can not contains be made a valid operator. The workaround i found is to use

!(input.shipment.sHIPMENTDESC not contains 'GINGER').

But life is easier when the not contains operator is available. Please advice.

Add more than 10 items to an mvel list with ASM Opitmizer crashes

Seems to only happen with the ASM Optimizer. Can work-around the issue by explicitly using a java.util.ArrayList.

Included here is a test case/class that demonstrates the issue.

We are "stuck" on mvel version 2.2.2.Final, and the issue is reproducible against the latest version 2.4.0.Final.

package test.rules;

import org.mvel2.MVEL;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.integration.impl.MapVariableResolverFactory;
import org.mvel2.optimizers.OptimizerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.Serializable;
import java.util.HashMap;

import static org.mvel2.MVEL.executeExpression;

/**
 * Test that demonstrates the Mvel issue.
 *
 * Software we use embeds MVEL and sets the default optimizer to ASM
 *  - OptimizerFactory.setDefaultOptimizer("ASM");
 *
 * If we create a list in Mvel and add more than 10 items to it, then
 *  "bad things happen" / it throws an Exception.
 *
 * We are able to work around this by explicitly creating an ArrayList.
 *
 * Workaround :
 *   FROM : list = [];
 *     TO : list = new java.util.ArrayList();
 */
@Test
public class MvelArrayTest {

    // Add more than 10 items to an mvel list, where we sometimes add null.
    // Then use java.util.Collections to replace all nulls with a default value
    // and use Collections.max to find the biggest value
    private final String biglistTestScript =
        "list = [];\n" +
        "list.add(1);\n" +
        "list.add(2);\n" +
        "list.add(3);\n" +
        "list.add(null);\n" + // null!
        "list.add(5);\n" +
        "list.add(6);\n" +
        "list.add(7);\n" +
        "list.add(8);\n" +
        "list.add(9);\n" +
        "list.add(10);\n" +
        "list.add(11);\n" +
        "list.add(12);\n" +
        "java.util.Collections.replaceAll( list, null, 25 );\n" + // replace nulls, with a big value
        "java.util.Collections.max( list );\n";  // return

    /**
     * Demonstrate the error.
     *
     * FYI this is what the stacktrace looks like when the error occurs.
     *
     *
        [Error: list = [];
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(null);
        list.add(5);
        list.add(6);
        list.add(7);
        list.add(8);
        list.add(9);
        list.add(10);
        list.add(11);
        list.add(12);
        java.util.Collections.replaceAll( list, null, 25 );
        java.util.Collections.max( list );
        ]
        [Near : {... list = []; ....}]
                     ^
        [Line: 1, Column: 1]

            at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.compileAccessor(ASMAccessorOptimizer.java:860)
            at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.optimizeAccessor(ASMAccessorOptimizer.java:245)
            at org.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
            at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
            at org.mvel2.MVELRuntime.execute(MVELRuntime.java:86)
            at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
            at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
            at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:113)
            at org.mvel2.MVEL.executeExpression(MVEL.java:942)
            at test.rules.MvelArrayTest.demonstrate_AsmOptimizerDiesWithBigList(MvelArrayTest.java:55)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
            at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
            at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
            at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
            at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
            at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
            at org.testng.TestRunner.privateRun(TestRunner.java:767)
            at org.testng.TestRunner.run(TestRunner.java:617)
            at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
            at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
            at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
            at org.testng.SuiteRunner.run(SuiteRunner.java:240)
            at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
            at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
            at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198)
            at org.testng.TestNG.runSuitesLocally(TestNG.java:1123)
            at org.testng.TestNG.run(TestNG.java:1031)
            at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
            at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
        Caused by: java.lang.reflect.InvocationTargetException
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:498)
            at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.getMethod(ASMAccessorOptimizer.java:2156)
            at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.compileAccessor(ASMAccessorOptimizer.java:759)
            ... 32 more
        Caused by: java.lang.NullPointerException
            at java.util.Collections.max(Collections.java:673)
            ... 38 more
     */
    @Test(expectedExceptions = org.mvel2.PropertyAccessException.class)
    public void demonstrate_AsmOptimizerDiesWithBigList() {

        OptimizerFactory.setDefaultOptimizer("ASM");
        Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
        VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());

        executeExpression(compileExpression, factory);
        Assert.fail( "If we got here, then the issue was fixed and this test should go away!" );
    }



    /////
    // Show that the other Optimizer types don't have this problem.
    //
    @Test
    public void demonstrate_reflectiveOptimizerWorksFine() {

        OptimizerFactory.setDefaultOptimizer("reflective");
        Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
        VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());

        int actual = (int) executeExpression(compileExpression, factory);
        Assert.assertEquals( actual, 25);
    }

    @Test
    public void demonstrate_dynamicOptimizerWorksFine() {

        OptimizerFactory.setDefaultOptimizer("dynamic");
        Serializable compileExpression = MVEL.compileExpression( biglistTestScript );
        VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());

        int actual = (int) executeExpression(compileExpression, factory);
        Assert.assertEquals( actual, 25);
    }


    ////
    // Show that adding less then 10 things to the list works fine
    //
    // Less than 10 items is fine
    private final String smallListTestScript =
        "list = [];\n" +
        "list.add(1);\n" +
        "list.add(2);\n" +
        "list.add(3);\n" +
        "list.add(null);\n" + // null!
        "list.add(5);\n" +
        "list.add(6);\n" +
        "java.util.Collections.replaceAll( list, null, 25 );\n" + // replace nulls, with a big value
        "java.util.Collections.max( list );\n";  // return

    @Test
    public void demonstrate_AsmOptimizerWithSmallListIsFine() {

        OptimizerFactory.setDefaultOptimizer("ASM");
        Serializable compileExpression = MVEL.compileExpression( smallListTestScript );
        VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap());

        int actual = (int) executeExpression(compileExpression, factory);
        Assert.assertEquals( actual, 25);
    }
}

StringIndexOutOfBoundsException

MVEL.compileExpression("1.0/25 or 1.0", new ParserContext());
produces some result.

But

MVEL.compileExpression("1.0/25 and 1.0", new ParserContext());
gives StringIndexOutOfBoundsException:

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1871)
    at org.mvel2.util.ErrorUtil.rewriteIfNeeded(ErrorUtil.java:17)
    at org.mvel2.compiler.ExpressionCompiler._compile(ExpressionCompiler.java:295)
    at org.mvel2.compiler.ExpressionCompiler.compile(ExpressionCompiler.java:52)
    at org.mvel2.MVEL.compileExpression(MVEL.java:810)

I think that both cases have incorrect behavior.

Need improve MVEL efficiency

Dear guys,

I used the MVEL to execute belong expression language as below:

errorMsg=(userName == empty?'姓名不能为空!':'')+ (userIdNo == empty?'身份证号码不能为空!':'')+ (registTime == empty?'注册日期不能为空!':'')+ (lastDegree == empty?'学历不能为空!':'')+ (incomeLevel == empty?'收入不能为空!':'')+ (userCardNo == empty?'银行卡号不能为空!':'')+ (userMobile == empty?'银行预留手机号不能为空!':'')+ (contactMobile == empty?'联系人手机号不能为空!':'')+ (applyIp == empty?'真实IP地址不能为空!':'')+ (MAC == empty?'MAC地址不能为空!':'')+ (devImei == empty?'IMEI/IDFA不能为空!':''); errorCode=(errorMsg== empty?'':10001);
My code:
MVEL.eval(language, Map)

Above code need cost 60 millisecond to finish executing this EL, so my question is "is there some ways to improve the efficiency, to reduce the time costing of above code?"

Thanks in advance
Wei

NPE When invoking method with null parameter

Caused by: java.lang.NullPointerException
at org.mule.mvel2.optimizers.impl.refl.nodes.MethodAccessor.argTypes(MethodAccessor.java:149)
at org.mule.mvel2.optimizers.impl.refl.nodes.MethodAccessor.getValue(MethodAccessor.java:59)
at org.mule.mvel2.optimizers.impl.refl.nodes.StaticReferenceAccessor.getValue(StaticReferenceAccessor.java:31)
at org.mule.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108)

DROOLS-1215 import function(s) with collision on declared Pojo field names

Following test make reference to DROOLS-1215, can be added to CoreConfidenceTests.

In the below example, first expression shall be intended as:
this.name
meaning the field 'name' of the Person pojo, however it is resolved as the name (static method) function which is imported.

This will make the first assertion fail.

The other assertions behave as expected.

  public void testDrools1215() {
    ParserConfiguration conf = new ParserConfiguration();
    boolean doImportNameMethod = true;
    if (doImportNameMethod) {
        Class<?> clazz = CoreConfidenceTests.class;
        Method nameMethod = null;
        for (Method m : clazz.getMethods()) {
            if (m.getName() == "name") {
                nameMethod = m;
            }
        }
        System.out.println(nameMethod);
        conf.addImport("name", nameMethod);
    }
    ParserContext pctx = new ParserContext( conf );
    pctx.setStrictTypeEnforcement(true);
    pctx.setStrongTyping(true);
    pctx.addInput("this", MyPerson.class);

    ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression("name == \"Matteo\"", pctx);
    System.out.println("stmt: " + stmt.getClass() + stmt);

    ExecutableStatement stmt2 = (ExecutableStatement) MVEL.compileExpression("name() == \"nameAsFunction\"", pctx);
    System.out.println("stmt2: " + stmt2.getClass() + stmt2);

    ExecutableStatement stmt3 = (ExecutableStatement) MVEL.compileExpression("Name == \"Matteo\"", pctx);
    System.out.println("stmt3: " + stmt3.getClass() + stmt3);

    MyPerson ctx = new MyPerson("Matteo");

    Object result1 = MVEL.executeExpression(stmt, ctx);
    System.out.println(result1);
    assertEquals(true, result1); // <<-- test fails because of this ambiguity, name should be this.name meaning field 'name' of pojo, not the function.

    Object result2 = MVEL.executeExpression(stmt2, ctx);
    System.out.println(result2);
    assertEquals(true, result2);

    Object result3 = MVEL.executeExpression(stmt3, ctx);
    System.out.println(result3);
    assertEquals(true, result3);
  }

  public static String name() {
      System.out.println("nameAsFunction");
      return "nameAsFunction";
  }

if/else if/else expression with trailing blanks does evaluate properly

Hi,

I am trying to upgrade to the current version of MVEL (2.4) and I found an existing expression that is not evaluated as before.
I can reproduce the issue with an if/else if/else combination when there are some trailing blanks or new line after the else block.
When there are no trailing blanks , the evaluation works fine.

I looked in the history to find when the problem appeared and it is just after the commit aef5d6d. From 86b3331 the tests fails

As a workaround I can still strip the expressions from all blanks characters.

Here are the tests I used:



    public void testWithTrailingNewLine() {

        String expression = "if (true) {'ok';} else if (false) {'ko';} else {'ko';}\n";
        Object result = MVEL.eval(expression);

        assertEquals("ok", result);

    }


    public void testWithTrailingBlank() {

        String expression = "if (true) {'ok';} else if (false) {'ko';} else {'ko';} ";
        Object result = MVEL.eval(expression);

        assertEquals("ok", result);

    }

    public void testWithoutTrailingBlank() {

        String expression = "if (true) {'ok';} else if (false) {'ko';} else {'ko';}";
        Object result = MVEL.eval(expression);

        assertEquals("ok", result);

    }


java.lang.IllegalAccessException: Class org.mvel2.optimizers.impl.refl.nodes.GetterAccessor can not access a member of class java.util.Collections$EmptyList with modifiers "public"

Hello,

A very simple expression list.empty failed on execution when differen iheritances of the List interface come to the context one by one.
Please, take a look at the following test case. It fails on the second execution.

public class MVELTest {

    public static void main(String... args) {
        (new MVELTest()).testEmptyListAccess();
    }

    private void testEmptyListAccess() {
        Serializable compiled = MVEL.compileExpression("list.empty");
        boolean result = MVEL.executeExpression(compiled, new Data(new ArrayList<>()), new MapVariableResolverFactory(new HashMap()), Boolean.class);
        assert result;
        result = MVEL.executeExpression(compiled, new Data(Collections.emptyList()), new MapVariableResolverFactory(new HashMap()), Boolean.class);
        assert result;
    }

    public final class Data {

        private final List<Object> list;

        Data(List<Object> list) {
            this.list = list;
        }

        public List<Object> getList() {
            return list;
        }
    }
}

IllegalArgumentException in org.mvel2.asm.ClassWriter

Getting following exception

Caused by: java.lang.IllegalArgumentException: value 30000
at org.mvel2.asm.ClassWriter.newConstItem(ClassWriter.java:1057)
at org.mvel2.asm.MethodWriter.visitLdcInsn(MethodWriter.java:1126)
at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.getMethod(ASMAccessorOptimizer.java:2084)
at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.compileAccessor(ASMAccessorOptimizer.java:782)
... 164 more

apparently caused by the optimizer that kicks in at some point.
The value "30000" is actually a BigDecimal constant in the expression, ie. "30000B".

BigDecimal is not a supported case in the ClassWriter.newConstItem() method.

Similarly to #96 and to [DROOLS-1215]

Similarly to #96 and to DROOLS-1215, the following test below demonstrate an ambiguity/collision between what shall be resolved as the Pojo field "empty", but it is instead resolved to the empty literal.

The test can be added to CoreConfidenceTests.

The test also describes a possible workaround from the user's perspective while defining the expression, aware of this conflict can use the actual name of the getter from the signature (getEmpty()) instead of the MVEL style of property accessor.

  public void testAlsoLiteralCollisionWithPojoField() {
    ParserConfiguration conf = new ParserConfiguration();
    ParserContext pctx = new ParserContext( conf );
    pctx.setStrictTypeEnforcement(true);
    pctx.setStrongTyping(true);
    pctx.addInput("this", ContainerPojo.class);

    ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression("empty == \"yes\"", pctx);

    System.out.println("stmt: " + stmt.getClass() + stmt);
    ExecutableStatement stmt2 = (ExecutableStatement) MVEL.compileExpression("getEmpty() == \"yes\"", pctx);
    System.out.println("stmt2: " + stmt2.getClass() + stmt2);

    ExecutableStatement stmt3 = (ExecutableStatement) MVEL.compileExpression("Empty == \"yes\"", pctx);
    System.out.println("stmt3: " + stmt3.getClass() + stmt3);

    ContainerPojo ctx = new ContainerPojo("yes");

    Object result1 = MVEL.executeExpression(stmt, ctx);
    System.out.println(result1);
    assertEquals(true, result1); // <<-- test fails because of this ambiguity, name should be this.empty meaning field 'name' of pojo, not the 'empty' literal.

    Object result2 = MVEL.executeExpression(stmt2, ctx);
    System.out.println(result2);
    assertEquals(true, result2);

    Object result3 = MVEL.executeExpression(stmt3, ctx);
    System.out.println(result3);
    assertEquals(true, result3);
  }

  public class ContainerPojo {
    private String empty;

    public ContainerPojo(String empty) {
        super();
        this.empty = empty;
    }

    public String getEmpty() {
        return empty;
    }

    public void setEmpty(String empty) {
        this.empty = empty;
    }

  }

MVEL.compileExpression return bad value on some multiplying numbers .

MVEL.compileExpression return bad value, for example:

check this code:
org.mvel2.compiler.ExecutableLiteral ee = (org.mvel2.compiler.ExecutableLiteral) MVEL.compileExpression("((0.0705000000)*(100000))");
System.out.println(ee.getLiteral());
the result will appear as 7049.999999999999 .

The cause for that is:

package org.mvel2.math , class MathProcessor , Method _doOperations .

This is calculating the type of the result
box(type2) > box(type1) ? box(type2) : box(type1)

which is being send into the method doPrimWrapperArithmetic

and calculating the result:
return toType(val1.doubleValue() * val2.doubleValue(), returnTarget);

but some case when multiplying W_INTEGER * Double can get float result
such as :

org.mvel2.compiler.ExecutableLiteral ee = (org.mvel2.compiler.ExecutableLiteral) MVEL.compileExpression("((0.0705000000)*(100000))");

But if you will try to return type as float it should be ok
such as this example:
Number d1 = 0.0705;
Number d2 = 100000;
System.out.println((float) (d2.doubleValue() * d1.doubleValue()));

Return types do not match

The following test will fail. In spite of getObj method declared as Object the getValue returns String not Object

index ea7661bb..8623fcdb 100644
--- a/src/test/java/org/mvel2/tests/core/CoreConfidenceTests.java
+++ b/src/test/java/org/mvel2/tests/core/CoreConfidenceTests.java
@@ -4515,6 +4515,19 @@ public class CoreConfidenceTests extends AbstractTest {
     Map vars = new HashMap() {{ put("a", new O1()); }};
     assertEquals("value", MVEL.executeExpression(MVEL.compileExpression("a.getObj().getValue()", parserContext), vars));
   }
+  
+
+  public static class O11 {
+	  public Object getObj() {
+		  return new O2();
+	  }
+  }
+  public void testInvokeMethodInAbstractClass2() {
+	  final ParserContext parserContext = new ParserContext();
+
+	  parserContext.addInput("a", O11.class);
+	  assertEquals(String.class, MVEL.analyze("a.getObj().getValue()", parserContext));
+  }
 
   public class Convention {
     private final Map<String, List<String>> comms;```

MVEL Guide may be deleted from WikiSource

Not sure where to post this or how big of an issue or current it is, but the language guide linked Guide in the readme is pending deletion from wikisource. Apparently it was ported to Wikipedia which rejected it under 'Not a Guide' and ported it to WikiSource, where it may be deleted due to copyright. (Document is listed as (defunct) Codehaus holding the copyright). Perhaps making it a github page would be helpful as this is the only real reference I've seen documenting the language.
Propossed Delete

SetterAccessor concurrency issue

SetterAccessor#setValue method uses coercionRequired instance variable to fallback to coercion if straight call fails with "argument type mismatch" exception.

Concurrency issue exists under heavy load though. coercionRequired variable can be changed to true by another thread, so when catch block is entered we always get new RuntimeException("unable to bind property", e).

Trivial fix is to cache coercionRequired instance variable in local variable, so both threads will fallback to coercion correctly.

This issue may exist in other classes which do fallback to coercion routine.

Unmatched right parenthesis on a method doesn't throw an error

We found an error, and while debugging it, we found out that if using an unmatched right parenthesis after a method, mvel doesn't find it as an error.

Example:

// this method throws an unbalanced braces error
MVEL.compileExpression("1 == 0 && (1 == 1))");

//but if I have a function
public static boolean test(boolean value) { return value; }
// then this method doesn't throw an error
MVEL.compileExpression("1 == 0 && test(true))");

Regular expression support

In the Mvel docs I see the following sentence "MVEL has largely been inspired by Java syntax, but has some fundamental differences aimed at making it more efficient as an expression language, such as operators that directly support collection, array and string matching, as well as regular expressions"

I couldn't find any information about how to use regex in MVEL in the docs. Can you update the docs or give some hint about it?

Java 9 forbids the use of "_"; build fails

Please stop using _ as the name of a method in various places. It is deprecated in Java 8, and illegal in Java 9.

You can temporarily work around this by setting the -source argument to 1.8 (or lower), but, if it's part of the public API, it desperately needs to be fixed so people can continue to use the class on Java 9, due out in ~two weeks.

public Map<K, V> _(K key, V value) {

API changes report for MVEL

Hi,

I'd like to share report on API changes and backward compatibility for the MVEL library: https://abi-laboratory.pro/java/tracker/timeline/mvel/

BC — binary compatibility
SC — source compatibility

The report is generated according to the article https://wiki.eclipse.org/Evolving_Java-based_APIs_2 by the https://github.com/lvc/japi-tracker tool for jars at http://central.maven.org/maven2/org/mvel/mvel2/.

Hope it will be helpful for users and maintainers of the library.

Thank you.

mvel-1

Add release notes

Add release notes to project. This will allow to understand changes and requirements for each release

java.lang.VerifyError: (class: ASMAccessorImpl_8096399931462518849630, method: getKnownEgressType signature: ()Ljava/lang/Class;) Illegal type in constant pool

MVEL occasionally throws exception flollowing:

**** COMPILER BUG! REPORT THIS IMMEDIATELY AT http://jira.codehaus.org/browse/mvel2
Expression: item.type

06-May-2016 15:14:09.648 SEVERE [http-apr-8080-exec-4] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [default] in context with path [] threw exception [Filter execution threw an exception] with root cause
java.lang.VerifyError: (class: ASMAccessorImpl_8096399931462518849630, method: getKnownEgressType signature: ()Ljava/lang/Class;) Illegal type in constant pool
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructor0(Class.java:3075)
at java.lang.Class.newInstance(Class.java:412)
at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer._initializeAccessor(ASMAccessorOptimizer.java:725)
at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.compileAccessor(ASMAccessorOptimizer.java:859)
at org.mvel2.optimizers.impl.asm.ASMAccessorOptimizer.optimizeAccessor(ASMAccessorOptimizer.java:243)
at org.mvel2.optimizers.dynamic.DynamicGetAccessor.optimize(DynamicGetAccessor.java:90)
at org.mvel2.optimizers.dynamic.DynamicGetAccessor.getValue(DynamicGetAccessor.java:64)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:42)
at org.mvel2.MVEL.executeExpression(MVEL.java:922)
at cn.webwheel.template.TemplateRenderer.output(TemplateRenderer.java:117)
at cn.webwheel.template.TemplateRenderer.write(TemplateRenderer.java:46)
at cn.webwheel.template.TemplateRenderer.write(TemplateRenderer.java:110)
at cn.webwheel.template.TemplateRenderer.write(TemplateRenderer.java:52)
at cn.webwheel.template.TemplateRenderer.render(TemplateRenderer.java:30)
at cn.webwheel.results.TemplateResultInterpreter.interpret(TemplateResultInterpreter.java:131)
at cn.webwheel.results.TemplateResultInterpreter.interpret(TemplateResultInterpreter.java:35)
at cn.webwheel.Main.interpretResult(Main.java:107)
at cn.webwheel.Main.process(Main.java:229)
at cn.webwheel.WebWheelFilter.doFilter(WebWheelFilter.java:78)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)

how to check whether a string contains some terms

I'm trying use mvel to evaluate a string contains expression

ParserContext context = ParserContext.create().stronglyTyped().withInput("$tag", String.class);
CompiledExpression expression = new ExpressionCompiler("$tag.contains('a') && !$tag.contains('b')", context).compile();
System.out.println(expression);

but, the compiledexpression was printed like this,

(null && $tag.contains('b'));

so, what should I do to check whether a string contains some terms or not? use regex pattern?

Remove bundled asm and add it as a dependency

It's not a good practice to bundle different projects together. It's more convenient to have one depend on another as maven perfectly allows and supports. I can provide a patch witch removes the bundled asm and instead relies on org.objectweb.asm. We use mvel like this (without bundled asm) in Fedora.

SandBox MVEL, class access policy / security

I would like to use MVEL as expression language for an application. Expressions must not pose a way to create a security exploit,... They should be expressions, not statements.

As MVEL is shortcut for MVFLEX Expression Language, it seemed as viable alternative.

I want to pass a context to evaluation, which would contain: data (map of string names paired to objects), and list of accessible classes (for instantiation).

Optimized access to java.util.Collections.SingletonList fails with IllegalAccessError

When using optimized access, usage of java.util.SingletonList fails with the following error:

java.lang.IllegalAccessError: tried to access class java.util.Collections$SingletonList from class ASMAccessorImpl_16174377441503300396160

Please note that in order to reproduce this problem, DynamicOptimizer.tenuringThreshold has to be set to 1, to forcibly turn on optimized accessors. With optimizations disabled, the problem does not occur.

Attaching failing test case.

OptimizedSingletonListAccessTest.txt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.