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