[rules-users] Using variables as map keys in MVEL in LHS

Edson Tirelli tirelli at post.com
Thu Jul 16 10:09:31 EDT 2009


   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 at 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 at lists.jboss.org
> http://lists.jboss.org/mailman/listinfo/rules-users
>
>


-- 
 Edson Tirelli
 JBoss Drools Core Development
 JBoss by Red Hat @ www.jboss.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20090716/0376700d/attachment.html 


More information about the rules-users mailing list