2 Replies Latest reply on May 26, 2009 11:05 AM by beve

    Drools 5.0.1GA upgrade

    beve

      I'm updating Drools to 5.0.1.GA and discovered an issue with the business_ruleservice_stateful quickstart.

      The following exception was shown when running the quickstart:

      org.drools.RuntimeDroolsException: Exception executing predicate customer.userName == $c.userName
       at org.drools.rule.PredicateConstraint.isAllowedCachedLeft(PredicateConstraint.java:302)
       at org.drools.common.SingleBetaConstraints.isAllowedCachedLeft(SingleBetaConstraints.java:138)
       at org.drools.reteoo.AccumulateNode.assertLeftTuple(AccumulateNode.java:153)
       at org.drools.reteoo.CompositeLeftTupleSinkAdapter.doPropagateAssertLeftTuple(CompositeLeftTupleSinkAdapter.java:145)
       at org.drools.reteoo.CompositeLeftTupleSinkAdapter.createAndPropagateAssertLeftTuple(CompositeLeftTupleSinkAdapter.java:57)
       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.jboss.internal.soa.esb.services.rules.DroolsRuleService.insertObjectsIntoWorkingMemory(DroolsRuleService.java:602)
       at org.jboss.internal.soa.esb.services.rules.DroolsRuleService.executeStatefulRules(DroolsRuleService.java:527)
       at org.jboss.internal.soa.esb.services.rules.DroolsRuleService.executeStatefulRules(DroolsRuleService.java:223)
       at org.jboss.internal.soa.esb.services.rules.RuleServiceCallHelper.executeRulesService(RuleServiceCallHelper.java:126)
       at org.jboss.soa.esb.actions.BusinessRulesProcessor.executeRulesService(BusinessRulesProcessor.java:121)
       at org.jboss.soa.esb.actions.BusinessRulesProcessor.process(BusinessRulesProcessor.java:97)
       at org.jboss.soa.esb.listeners.message.ActionProcessingPipeline.processPipeline(ActionProcessingPipeline.java:634)
       at org.jboss.soa.esb.listeners.message.ActionProcessingPipeline.processPipeline(ActionProcessingPipeline.java:586)
       at org.jboss.soa.esb.listeners.message.ActionProcessingPipeline.process(ActionProcessingPipeline.java:420)
       at org.jboss.soa.esb.listeners.message.MessageAwareListener$TransactionalRunner.run(MessageAwareListener.java:548)
       at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
       at java.lang.Thread.run(Thread.java:595)
      Caused by: [Error: unable to access property (null parent): userName]
      [Near : {... Unknown ....}]
       ^
      [Line: 1, Column: 0]
       at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:861)
       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.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)
       ... 24 more
      
      


      Three objects are inserted into the working memory which are:
      1. ESB Message object instance.
      2. OrderHeader object instance. This object has a customer field that is null.
      3. Customer object instance which is not null.

      Looking at our rules in OrderDiscountOnMultipleOrders.drl:
      rule "Apply 10% discount to customer if totalPrice of all their orders is over 100"
       dialect "mvel"
       when
       $c : Customer()
       $i : Number(intValue >= 100) from accumulate ( OrderHeader( customer.userName == $c.userName, $totalAmount : totalAmount),
       sum( $totalAmount ) );
       then
       $c.setOrderDiscount( 10 );
       System.out.println( "Customer " + $c.getUserName() + " now has a shopping total of " + $i );
      end


      We are expecting the OrderHeader's customer to have been populated as we are using it to check the userName : "customer.userName == $c.userName".
      How/why this worked with the previous version of Drools I'm not sure and need to find out. Perhaps the older version did a check for null first and the new version does not.
      Anyway this seems to be an error with the quickstart and I've updated the src/org/jboss/soa/esb/samples/quickstart/businessrulesstateful/SetupMessage.java and now setting the customer on the header instance:
      header.setCustomer(customer);


      Also when upgrading I've noticed that a drools package (org.drools.rule.Package) that has been serialized with one version cannot be deserialized with another. You need to re-create the drl and store is in a pkg file. We do this in two places, one is in a unit test in the jbrules module and the other is in the business_ruleservice_ruleAgent quickstart. Both now have an ant target named "generatePackageFile" that will perform this task which can be used when upgrading. This info is also in the readme.txt of jbrules.


      I also needed to remove the jndi.properties file from lib/ext/drools-persistence-jpa-5.0.1.jar which contained:
      java.naming.factory.initial=bitronix.tm.jndi.BitronixInitialContextFactory

      This was messing with our qa tests as we don't provide that class.

      As always comments or questions are welcome.

      /Daniel


        • 1. Re: Drools 5.0.1GA upgrade
          jeffdelong

          Glad to see you are upgrading to Drools 5.0.1.GA.

          I suspect the problem is in the Smooks transformation.

          If you look at the smooks-res.xml (well at least the one in SOA-P-4.3.CP01 quickstarts), if has the param "setOn" specified for the Customer to set it on the OrderHeader.

          I believe this might have changed with recent versions of Smooks, although I though it was deprecated and still allowed (at least with Smooks in SOA-P-4.3.CP01). I can't remember off hand the new was to set a relationship with Smooks.

          Also, the SetupMessage class does not have to add the customer and orderHeader to the messsage. Instead, the SmooksAction can use the setPayloadLocation to something like orderPayload, and then the object-paths in the BusienssRulesProcessor action can specify body.orderPayload.TheCustomer, etc.

          Setting the dispose and continue property would still be required, and could be done in the SetupMessage class or in a groovy script.

          When you have a chance I would like to talk with you about how to support the new CEP features in Drools 5.0.1.GA. It is the "real way" to do stateful rules of the type this quickstart is intended to illustrate.

          Jeff

          • 2. Re: Drools 5.0.1GA upgrade
            beve

            Hi Jeff,

            ah, good point(s)! I'll take a look at this first thing tomorrow.

            When you have a chance I would like to talk with you about how to support the new CEP features in Drools 5.0.1.GA

            Will you be at J1 next week? Perhaps we could talk then if you are.

            Thanks,

            /Daniel