MVFLEX Expression Language (MVEL) is a hybrid dynamic/statically typed, embeddable Expression Language and runtime for the Java Platform.
git clone https://github.com/mvel/mvel.git
cd mvel
mvn clean install
MVEL (MVFLEX Expression Language)
Home Page: http://mvel.documentnode.com/
License: Apache License 2.0
MVFLEX Expression Language (MVEL) is a hybrid dynamic/statically typed, embeddable Expression Language and runtime for the Java Platform.
git clone https://github.com/mvel/mvel.git
cd mvel
mvn clean install
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
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
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.
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)
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
I want to use mvel in my project , is this an active project ? or is there an alternative that you might recommend
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.
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.
Hello,
Is there a way to force BigDecimal as the default conversion ? I mean
10.503 // become a BigDecimal and not a double .
because "(0.08*20.0)/20.00)" evaluation give me 0.08000000000000000166533453693773481
Thanks in advance
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).
Hi Someone can tell me how to get variables and functions from mvel expression
for example:
String exp = "Math.ceil( (double) x / 3 ) + bb";
Thanks
Especially for reflective optimization mode
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?
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)
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?
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?
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)":
MVEL.eval(exp, ctxObj)
, it is correctly evaluated
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!
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?
In java8, there is a type Optional . eg.
Class User{ String name; Optional<Integer> age; }
now parse age>0
return always false. does mvel have plan to support Optional?
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.
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);
}
}
https://en.wikisource.org/wiki/MVEL_Language_Guide no longer works.
Is this documentation available elsewhere?
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.
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
Such as "System.exit(0)" "Runtime.getRuntime().exec('rm -rf /')"
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)
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 the line
// (
is included in a script, it will give an error: [Error: unbalanced braces ( ... )]. This is true even if a comment afterward has a closing parenthesis.
The line
// (bla bla)
is ok
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);
}
We ran into an issue were the second run of a compiled expression fails when using binary operator and nullsafe operator.
Test case and output can be found here: https://gist.github.com/domkun/2cd2e795c6e4df2bbfd692257a55a4bf
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;
}
}
}
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, 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, 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()));
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;```
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#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.
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))");
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?
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.
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.
Add release notes to project. This will allow to understand changes and requirements for each release
MVEL uses the hashCodes of property names to cache accessors.
Using String hashcodes for something like that is pretty bad.
Even simple property names collide: "Aa" and "BB" - and will return or set the same property!
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)
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?
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.
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).
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.