<br><font size=2 face="sans-serif">Hello,</font>
<br>
<br><font size=2 face="sans-serif">Again, I'm working on converting my
project that used Drools 4.0.7 to 5.0.1.</font>
<br>
<br><font size=2 face="sans-serif">I've run across a problem with a rule
that accesses a map in the LHS using a variable as the key. &nbsp;When
MVEL tries to resolve this, it appears that it is not evaluating the variable
before accessing the map. &nbsp;I've modified the Shopping example from
the Drools 5.0.1 Examples to recreate the issue in a simpler setting.</font>
<br>
<br><font size=2 face="sans-serif">This is the rule (I removed all the
other rules for this example)</font>
<br><font size=2 face="Courier New"><b>rule</b> &quot;Cart notification&quot;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; <b>salience</b> 10</font>
<br>
<br><font size=2 face="Courier New">&nbsp; &nbsp; <b>when</b></font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; $p : Product(
$productName : name)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; $c : Customer(
cart[$productName] == $p) &nbsp; &nbsp; &nbsp;</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; <b>then</b></font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(
&quot;Customer &quot; + $c.name + &quot; has &quot; + $p.name + &quot;
in cart&quot;);</font>
<br><font size=2 face="Courier New"><b>end</b> &nbsp;</font>
<br>
<br><font size=2 face="sans-serif">I added the following to the Customer
class:</font>
<br>
<br><font size=2 face="Courier New"><b>private</b> Map&lt;String,Product&gt;
cart = <b>new</b> HashMap&lt;String, Product&gt;();</font>
<br><font size=2 face="Courier New"><b>public</b> Map&lt;String, Product&gt;
getCart() {</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; <b>return</b> cart;</font>
<br><font size=2 face="Courier New">}</font>
<br>
<br><font size=2 face="Courier New">and I modified the main method to be:</font>
<br>
<br><font size=2 face="Courier New"><b>public</b> <b>static</b> <b>final</b>
<b>void</b> main(String[] args) <b>throws</b> Exception {</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; <b>final</b> KnowledgeBuilder
kbuilder = KnowledgeBuilderFactory.<i>newKnowledgeBuilder</i>();</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; kbuilder.add( ResourceFactory.<i>newClassPathResource</i>(
&quot;Shopping.drl&quot;, ShoppingExample.<b>class</b> ),</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ResourceType.<i>DRL</i>
);</font>
<br>
<br><font size=2 face="Courier New">&nbsp; &nbsp; <b>final</b> KnowledgeBase
kbase = KnowledgeBaseFactory.<i>newKnowledgeBase</i>();</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; kbase.addKnowledgePackages(
kbuilder.getKnowledgePackages() );</font>
<br>
<br><font size=2 face="Courier New">&nbsp; &nbsp; <b>final</b> StatefulKnowledgeSession
ksession = kbase.newStatefulKnowledgeSession();</font>
<br>
<br><font size=2 face="Courier New">&nbsp; &nbsp; Customer mark = <b>new</b>
Customer( &quot;mark&quot;,</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; 0 );</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; ksession.insert( mark
);</font>
<br>
<br><font size=2 face="Courier New">&nbsp; &nbsp; Product shoes = <b>new</b>
Product( &quot;shoes&quot;,</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;60 );</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; ksession.insert( shoes
);</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; </font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; mark.getCart().put(&quot;shoes&quot;,
shoes);</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; </font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; <u>ksession</u>.fireAllRules();</font>
<br><font size=2 face="Courier New">}</font>
<br>
<br><font size=2 face="sans-serif">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. &nbsp;</font>
<br><font size=2 face="sans-serif">What I would expect to happen is:</font>
<br><font size=2 face="sans-serif">&nbsp; the Product pattern would match
the shoes Product that is inserted into the ksession, the $productName
variable would contain the value &quot;shoes&quot;</font>
<br><font size=2 face="sans-serif">&nbsp; the Customer fact, mark, would
be matched with the second pattern in the rule because cart[&quot;shoes&quot;]
should resolve to the shoes fact which is $p in the rule</font>
<br><font size=2 face="sans-serif">&nbsp; The message should print</font>
<br>
<br><font size=2 face="sans-serif">What actually happens is an error message:</font>
<br>
<br><font size=2 face="Courier New">Exception in thread &quot;main&quot;
<u>org.drools.RuntimeDroolsException</u>: Exception executing predicate
cart[$productName] == $p</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.rule.PredicateConstraint.isAllowedCachedLeft(<u>PredicateConstraint.java:302</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.common.SingleBetaConstraints.isAllowedCachedLeft(<u>SingleBetaConstraints.java:138</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.reteoo.JoinNode.assertLeftTuple(<u>JoinNode.java:114</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateAssertLeftTuple(<u>SingleLeftTupleSinkAdapter.java:117</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.reteoo.SingleLeftTupleSinkAdapter.createAndPropagateAssertLeftTuple(<u>SingleLeftTupleSinkAdapter.java:78</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.reteoo.LeftInputAdapterNode.assertObject(<u>LeftInputAdapterNode.java:142</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(<u>SingleObjectSinkAdapter.java:42</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.reteoo.ObjectTypeNode.assertObject(<u>ObjectTypeNode.java:185</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.reteoo.EntryPointNode.assertObject(<u>EntryPointNode.java:146</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.common.AbstractWorkingMemory.insert(<u>AbstractWorkingMemory.java:1046</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.common.AbstractWorkingMemory.insert(<u>AbstractWorkingMemory.java:1001</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.common.AbstractWorkingMemory.insert(<u>AbstractWorkingMemory.java:788</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.impl.StatefulKnowledgeSessionImpl.insert(<u>StatefulKnowledgeSessionImpl.java:216</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.examples.ShoppingExample.main(<u>ShoppingExample.java:32</u>)</font>
<br><font size=2 face="Courier New">Caused by: [Error: unable to resolve
method: java.util.HashMap.$productName() [arglength=0]]</font>
<br><font size=2 face="Courier New">[Near : {... Unknown ....}]</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp;^</font>
<br><font size=2 face="Courier New">[Line: 1, Column: 0]</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(<u>ReflectiveAccessorOptimizer.java:906</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(<u>ReflectiveAccessorOptimizer.java:585</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(<u>ReflectiveAccessorOptimizer.java:313</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(<u>ReflectiveAccessorOptimizer.java:138</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.ast.ASTNode.getReducedValueAccelerated(<u>ASTNode.java:133</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.compiler.ExecutableAccessor.getValue(<u>ExecutableAccessor.java:37</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getCollectionProperty(<u>ReflectiveAccessorOptimizer.java:633</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(<u>ReflectiveAccessorOptimizer.java:319</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(<u>ReflectiveAccessorOptimizer.java:138</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.ast.ASTNode.getReducedValueAccelerated(<u>ASTNode.java:133</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.ast.BinaryOperation.getReducedValueAccelerated(<u>BinaryOperation.java:102</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.MVELRuntime.execute(<u>MVELRuntime.java:85</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.compiler.CompiledExpression.getValue(<u>CompiledExpression.java:104</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.mvel2.MVEL.executeExpression(<u>MVEL.java:978</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.base.mvel.MVELPredicateExpression.evaluate(<u>MVELPredicateExpression.java:75</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; at
org.drools.rule.PredicateConstraint.isAllowedCachedLeft(<u>PredicateConstraint.java:295</u>)</font>
<br><font size=2 face="Courier New">&nbsp; &nbsp; &nbsp; &nbsp; ...
13 more</font>
<br>
<br><font size=2 face="sans-serif">Is this a bug in MVEL or Drools, or
am I using the map access incorrectly?</font>
<br>
<br><font size=2 face="sans-serif">Thanks,</font>
<br><font size=2 face="sans-serif"><br>
</font><font size=3>Steve Ronderos</font>