Thanks Edson, worked like a charm!

Steve Ronderos

rules-users-bounces@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@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@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
> _______________________________________________
> rules-users mailing list
> rules-users@lists.jboss.org
>
http://lists.jboss.org/mailman/listinfo/rules-users