[rules-users] Using variables as map keys in MVEL in LHS
Steve Ronderos
steve.ronderos at ni.com
Thu Jul 16 09:04:07 EDT 2009
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20090716/2dd696a4/attachment.html
More information about the rules-users
mailing list