Hello,
Could please, somebody help to work around the following issue:
A simple check a list on emptynes couses java.lang.IllegalAccessException when differen iheritances of the List interface come to the context one by one.
Actually this is not Drools issue but mvel, but I hope someone suggest a solution here, because MVEL issue tracker is not very active.
Please, take a look at the following rule and code to launch it:
package com.test
import com.test.DroolsTest.Data;
rule "testRule"
when
$data : Data( list.empty )
then
System.out.println("List is empty");
end
package com.test;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class DroolsTest {
private static List<Data> data = Arrays.asList(new Data(new ArrayList<>()), new Data(Collections.emptyList()));
public static void main(String... args) {
try {
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-rules");
for (Data d : data) {
kSession.insert(d);
}
kSession.fireAllRules();
} catch (Throwable t) {
t.printStackTrace();
}
}
public static class Data {
private final List<Object> list;
Data(List<Object> list) {
this.list = list;
}
public List<Object> getList() {
return list;
}
}
}
Execution fails with the followin exception:
java.lang.RuntimeException: Error evaluating constraint 'list.empty' in [Rule "testRule" in rule.drl]
at org.drools.core.rule.constraint.MvelConstraint.evaluate(MvelConstraint.java:268)
at org.drools.core.rule.constraint.MvelConstraint.isAllowed(MvelConstraint.java:216)
at org.drools.core.reteoo.AlphaNode.assertObject(AlphaNode.java:139)
at org.drools.core.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:70)
at org.drools.core.reteoo.ObjectTypeNode.propagateAssert(ObjectTypeNode.java:320)
at org.drools.core.phreak.PropagationEntry$Insert.propagate(PropagationEntry.java:161)
at org.drools.core.phreak.PropagationEntry$Insert.execute(PropagationEntry.java:166)
at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:96)
at org.drools.core.phreak.SynchronizedPropagationList.flush(SynchronizedPropagationList.java:91)
at org.drools.core.common.DefaultAgenda.fireLoop(DefaultAgenda.java:1051)
at org.drools.core.common.DefaultAgenda.internalFireAllRules(DefaultAgenda.java:1014)
at org.drools.core.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1006)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.internalFireAllRules(StatefulKnowledgeSessionImpl.java:1320)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1311)
at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1295)
at com.test.issue42452.drools.DroolsTest.main(DroolsTest.java:25)
Caused by: java.lang.RuntimeException: cannot invoke getter: getList [declr.class: com.test.issue42452.drools.DroolsTest$Data; act.class: com.test.issue42452.drools.DroolsTest$Data] (see trace)
at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:74)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:108)
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:929)
at org.drools.core.util.MVELSafeHelper$RawMVELEvaluator.executeExpression(MVELSafeHelper.java:496)
at org.drools.core.rule.constraint.MvelConditionEvaluator.evaluate(MvelConditionEvaluator.java:113)
at org.drools.core.rule.constraint.MvelConditionEvaluator.evaluate(MvelConditionEvaluator.java:89)
at org.drools.core.rule.constraint.MvelConstraint.evaluate(MvelConstraint.java:266)
... 15 more
Caused by: java.lang.RuntimeException: unable to invoke method
at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.executeOverrideTarget(GetterAccessor.java:143)
at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:50)
at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:40)
... 24 more
Caused by: 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"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Method.invoke(Method.java:491)
at org.mvel2.optimizers.impl.refl.nodes.GetterAccessor.executeOverrideTarget(GetterAccessor.java:139)
... 26 more
Is there any way to make MVEL optimization smarter or turn it off?