Thanks Edson, worked like a charm!
Steve Ronderos
rules-users-bounces(a)lists.jboss.org wrote on 07/16/2009 09:09:31 AM:
[image removed]
Re: [rules-users] Using variables as map keys in MVEL in LHS
Edson Tirelli
to:
Rules Users List
07/16/2009 09:11 AM
Sent by:
rules-users-bounces(a)lists.jboss.org
Please respond to Rules Users List
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(a)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(a)lists.jboss.org
http://lists.jboss.org/mailman/listinfo/rules-users
--
Edson Tirelli
JBoss Drools Core Development
JBoss by Red Hat @
www.jboss.com
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
http://lists.jboss.org/mailman/listinfo/rules-users