[rules-users] Using variables as map keys in MVEL in LHS
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 MapString,Product cart = new HashMapString, Product(); public MapString, 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
Re: [rules-users] Using variables as map keys in MVEL in LHS
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.ronde...@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* MapString,Product cart = *new* HashMapString, Product(); *public* MapString, 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
Re: [rules-users] Using variables as map keys in MVEL in LHS
Thanks Edson, worked like a charm! Steve Ronderos rules-users-boun...@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-boun...@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.ronde...@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 MapString,Product cart = new HashMapString, Product(); public MapString, 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(