This was a bug in one of the MVEL versions that is fixed. Can you update your MVEL jar to one of the latest releases? I think it is 2.0.12.
[]s
Edson
2009/7/16 Steve Ronderos
<steve.ronderos@ni.com>
Hello,
Again, I'm working on converting my
project that used Drools 4.0.7 to 5.0.1.
I've run across a problem with a rule
that accesses a map in the LHS using a variable as the key. When
MVEL tries to resolve this, it appears that it is not evaluating the variable
before accessing the map. I've modified the Shopping example from
the Drools 5.0.1 Examples to recreate the issue in a simpler setting.
This is the rule (I removed all the
other rules for this example)
rule "Cart notification"
salience 10
when
$p : Product(
$productName : name)
$c : Customer(
cart[$productName] == $p)
then
System.out.println(
"Customer " + $c.name + " has " + $p.name + "
in cart");
end
I added the following to the Customer
class:
private Map<String,Product>
cart = new HashMap<String, Product>();
public Map<String, Product>
getCart() {
return cart;
}
and I modified the main method to be:
public static final
void main(String[] args) throws Exception {
final KnowledgeBuilder
kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add( ResourceFactory.newClassPathResource(
"Shopping.drl", ShoppingExample.class ),
ResourceType.DRL
);
final KnowledgeBase
kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(
kbuilder.getKnowledgePackages() );
final StatefulKnowledgeSession
ksession = kbase.newStatefulKnowledgeSession();
Customer mark = new
Customer( "mark",
0 );
ksession.insert( mark
);
Product shoes = new
Product( "shoes",
60 );
ksession.insert( shoes
);
mark.getCart().put("shoes",
shoes);
ksession.fireAllRules();
}
So basically, I added a map to Customer,
inserted one item and made a rule that will use a variable as a key for
that map.
What I would expect to happen is:
the Product pattern would match
the shoes Product that is inserted into the ksession, the $productName
variable would contain the value "shoes"
the Customer fact, mark, would
be matched with the second pattern in the rule because cart["shoes"]
should resolve to the shoes fact which is $p in the rule
The message should print
What actually happens is an error message:
Exception in thread "main"
org.drools.RuntimeDroolsException: Exception executing predicate
cart[$productName] == $p
at
org.drools.rule.PredicateConstraint.isAllowedCachedLeft(PredicateConstraint.java:302)
at
org.drools.common.SingleBetaConstraints.isAllowedCachedLeft(SingleBetaConstraints.java:138)
at
org.drools.reteoo.JoinNode.assertLeftTuple(JoinNode.java:114)
at
org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:117)
at
org.drools.reteoo.SingleLeftTupleSinkAdapter.createAndPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:78)
at
org.drools.reteoo.LeftInputAdapterNode.assertObject(LeftInputAdapterNode.java:142)
at
org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:42)
at
org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:185)
at
org.drools.reteoo.EntryPointNode.assertObject(EntryPointNode.java:146)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:1046)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:1001)
at
org.drools.common.AbstractWorkingMemory.insert(AbstractWorkingMemory.java:788)
at
org.drools.impl.StatefulKnowledgeSessionImpl.insert(StatefulKnowledgeSessionImpl.java:216)
at
org.drools.examples.ShoppingExample.main(ShoppingExample.java:32)
Caused by: [Error: unable to resolve
method: java.util.HashMap.$productName() [arglength=0]]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0]
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:906)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:585)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:313)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:138)
at
org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:133)
at
org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:37)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getCollectionProperty(ReflectiveAccessorOptimizer.java:633)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:319)
at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:138)
at
org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:133)
at
org.mvel2.ast.BinaryOperation.getReducedValueAccelerated(BinaryOperation.java:102)
at
org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
at
org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:104)
at
org.mvel2.MVEL.executeExpression(MVEL.java:978)
at
org.drools.base.mvel.MVELPredicateExpression.evaluate(MVELPredicateExpression.java:75)
at
org.drools.rule.PredicateConstraint.isAllowedCachedLeft(PredicateConstraint.java:295)
...
13 more
Is this a bug in MVEL or Drools, or
am I using the map access incorrectly?
Thanks,
Steve Ronderos
_______________________________________________
rules-users mailing list
rules-users@lists.jboss.org
http://lists.jboss.org/mailman/listinfo/rules-users
--
Edson Tirelli
JBoss Drools Core Development
JBoss by Red Hat @ www.jboss.com