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