[rules-users] Drool Rule Error with "or not" condition

Mark Proctor mproctor at codehaus.org
Wed Dec 2 13:32:02 EST 2009


Shah, Malay wrote:
> Mark,
>  
> In this case, the object types that are bound don't have "not"/"or" 
> conditions surrounding them (ExecutionOrderHist_core0 and 
> ExecutionHist_core0). So, these objects would always be there when the 
> rule is fired. Why would it still not identify and populate the 
> variables of the objects, and instead try to cast one object to another?
We generate one eval or one consequence, drools and java is type safe so 
in that generated piece of code we have ot assume a type. We generate 
the code using the type as specified in the binding. If the binding ends 
up with different object types that are not castable, then it's going to 
fail. Sure we could add more intelligence to the build process to 
generate an eval or a consequence that takes care of the different 
non-castable object types, but currently we don't and probably won't add 
that, unless it's a user contribution.

Mark
>  
> Thanks
>  
> Malay Shah
>  
>  
> ------------------------------------------------------------------------
> *From:* rules-users-bounces at lists.jboss.org 
> [mailto:rules-users-bounces at lists.jboss.org] *On Behalf Of *Mark Proctor
> *Sent:* Wednesday, December 02, 2009 12:44 PM
> *To:* Rules Users List
> *Subject:* Re: [rules-users] Drool Rule Error with "or not" condition
>
> when using 'or' the bindings and the object types for those bindings 
> must balance for each logical outcome.
>
> Mark
> Shah, Malay wrote:
>> Thanks W.
>>  
>> I removed the binding of EtsExecutionOrderXref_core00, and it looked 
>> good. But I am getting ClassCastException when adding new facts and 
>> conditions. I now have a new fact (EtsExecutionHist_core0) and an 
>> eval statement to check if the rule has already been fired for a 
>> unique key that is determined by variables in EtsExecutionHist_core0 
>> fact.
>>  
>> Exception in thread "main" org.drools.RuntimeDroolsException: 
>> !(violations.containsKey("S-50_EtsExecutionHist_core" + "_entityOID_" 
>> + EtsExecutionHist_core0_entityOID
>> + "_entityVID_" + EtsExecutionHist_core0_entityVID
>> )) : *[Error: com.ms.ieddata.etsdb.model.EtsExecutionOrderHist_core 
>> cannot be cast to com.ms.ieddata.etsdb.model.EtsExecutionHist_core]
>> *
>> When I don't have the eval statement, the rule works perfectly well. 
>> Also, I checked that if I flip the order of defining facts in the 
>> rule (i.e. having EtsExecutionHist_core0 fact before 
>> EtsExecutionOrderHist_core0), the rule works fine.
>>  
>> Below is the drool code and the error:
>>  
>> *Drool Rule:*
>>  
>> package S_50
>>  
>> import com.ms.ieddata.dataQuality.violation.Violation;
>> import com.ms.ieddata.etsdb.model.EtsExecutionOrderHist_core;
>> import com.ms.ieddata.etsdb.model.EtsExecutionHist_core;
>> import com.ms.ieddata.etsdb.model.EtsExecutionOrderXref_core;
>> global java.util.HashMap violations;
>> dialect "mvel"
>> rule "Legacy ETSDB Rule"
>> when
>>         EtsExecutionOrderHist_core0:EtsExecutionOrderHist_core
>>         (
>>             customerOrFirm != "0"
>>         )
>>         EtsExecutionHist_core0:EtsExecutionHist_core
>>         (
>>             parentOID == EtsExecutionOrderHist_core0.entityOID,
>>             lastCapacity == "1",
>>             application != "MMETL",
>> *            EtsExecutionHist_core0_entityOID:entityOID,
>>             EtsExecutionHist_core0_entityVID:entityVID*
>>         )
>>         EtsExecutionOrderXref_core
>>         (
>>             entityOID == EtsExecutionOrderHist_core0.entityOID,
>>             entityRID == EtsExecutionOrderHist_core0.entityRID,
>>             entityVID == EtsExecutionOrderHist_core0.entityVID,
>>             referenceID != "2" && referenceIDType == "orderSubCapacity"
>>         )
>>         or
>>         not(EtsExecutionOrderXref_core
>>                 (
>>                     entityOID == EtsExecutionOrderHist_core0.entityOID,
>>                     entityRID == EtsExecutionOrderHist_core0.entityRID,
>>                     entityVID == EtsExecutionOrderHist_core0.entityVID,
>>                     referenceIDType == "orderSubCapacity"
>>                 )
>>             )
>> *eval(!(violations.containsKey("S-50_EtsExecutionHist_core" + 
>> "_entityOID_" + EtsExecutionHist_core0_entityOID + "_entityVID_" + 
>> EtsExecutionHist_core0_entityVID)))*
>> then
>>     System.out.println("Rule Fired");
>> end
>>  
>> *Exception:*
>>  
>> Exception in thread "main" org.drools.RuntimeDroolsException: 
>> !(violations.containsKey("S-50_EtsExecutionHist_core" + "_entityOID_" 
>> + EtsExecutionHist_core0_entityOID
>> + "_entityVID_" + EtsExecutionHist_core0_entityVID
>> )) : *[Error: com.ms.ieddata.etsdb.model.EtsExecutionOrderHist_core 
>> cannot be cast to com.ms.ieddata.etsdb.model.EtsExecutionHist_core]
>> *[Near : {... Unknown ....}]
>>              ^
>> [Line: 1, Column: 0]
>>  at org.drools.rule.EvalCondition.isAllowed(EvalCondition.java:122)
>>  at 
>> org.drools.reteoo.EvalConditionNode.assertLeftTuple(EvalConditionNode.java:180)
>>  at 
>> org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:117)
>>  at 
>> org.drools.reteoo.SingleLeftTupleSinkAdapter.propagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:34)
>>  at org.drools.reteoo.NotNode.assertLeftTuple(NotNode.java:123)
>>  at 
>> org.drools.reteoo.CompositeLeftTupleSinkAdapter.doPropagateAssertLeftTuple(CompositeLeftTupleSinkAdapter.java:145)
>>  at 
>> org.drools.reteoo.CompositeLeftTupleSinkAdapter.propagateAssertLeftTuple(CompositeLeftTupleSinkAdapter.java:39)
>>  at org.drools.reteoo.JoinNode.assertLeftTuple(JoinNode.java:116)
>>  at 
>> org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:117)
>>  at 
>> org.drools.reteoo.SingleLeftTupleSinkAdapter.createAndPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:78)
>>  at 
>> org.drools.reteoo.LIANodePropagation.doPropagation(LIANodePropagation.java:47)
>>  at 
>> org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:649)
>>  at 
>> org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:637)
>>  at 
>> org.drools.reteoo.ReteooStatelessSession.execute(ReteooStatelessSession.java:203)
>>  at com.ms.ruleutils.RuleProcessor.process(RuleProcessor.java:142)
>>  at com.ms.ruleutils.RuleProcessor.process(RuleProcessor.java:73)
>>  at 
>> com.ms.ieddata.dataQuality.dqWithRR.DQCommandLineMain.performDQ(DQCommandLineMain.java:291)
>>  at 
>> com.ms.ieddata.dataQuality.dqWithRR.DQCommandLineMain.runEngine(DQCommandLineMain.java:196)
>>  at 
>> com.ms.ieddata.dataQuality.dqWithRR.DQCommandLineMain.main(DQCommandLineMain.java:170)
>> Caused by: [Error: 
>> com.ms.ieddata.etsdb.model.EtsExecutionOrderHist_core cannot be cast 
>> to com.ms.ieddata.etsdb.model.EtsExecutionHist_core]
>> [Near : {... Unknown ....}]
>>              ^
>> [Line: 1, Column: 0]
>>  at 
>> org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:388)
>>  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.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:37)
>>  at 
>> org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:833)
>>  at 
>> org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:315)
>>  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.ast.Substatement.getReducedValueAccelerated(Substatement.java:40)
>>  at 
>> org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:37)
>>  at org.mvel2.ast.Negation.getReducedValueAccelerated(Negation.java:44)
>>  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.MVELEvalExpression.evaluate(MVELEvalExpression.java:83)
>>  at org.drools.rule.EvalCondition.isAllowed(EvalCondition.java:117)
>>  ... 18 more
>> Caused by: java.lang.ClassCastException: 
>> com.ms.ieddata.etsdb.model.EtsExecutionOrderHist_core cannot be cast 
>> to com.ms.ieddata.etsdb.model.EtsExecutionHist_core
>>  at 
>> org.drools.base.com.ms.ieddata.etsdb.model.EtsExecutionHist_core32580467$getEntityVID.getValue(Unknown 
>> Source)
>>  at org.drools.base.ClassFieldReader.getValue(ClassFieldReader.java:91)
>>  at org.drools.rule.Declaration.getValue(Declaration.java:244)
>>  at 
>> org.drools.base.mvel.DroolsMVELPreviousDeclarationVariable.getValue(DroolsMVELPreviousDeclarationVariable.java:67)
>>  at 
>> org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:446)
>>  at 
>> org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:312)
>>  ... 35 more
>>  
>> Am I missing something here? I think this is a perfectly valid rule, 
>> where eval statement is needed to make sure we don't fire the rule 
>> multiple times. I don't have the entire consequence section in the 
>> drool code above, but we perform multiple actions if rules are fired. 
>> I am trying to get to the bottom of this, because we generate these 
>> Drool Rule Code on the fly, and I can't determine the order in which 
>> facts (and their variables) would be defined.
>>  
>> Any kind of help here would be much appreciated.
>>  
>> Thanks
>>  
>> Malay Shah
>>
>>  
>>
>> ------------------------------------------------------------------------
>> *From:* rules-users-bounces at lists.jboss.org 
>> [mailto:rules-users-bounces at lists.jboss.org] *On Behalf Of *Wolfgang Laun
>> *Sent:* Wednesday, December 02, 2009 1:47 AM
>> *To:* Rules Users List
>> *Subject:* Re: [rules-users] Drool Rule Error with "or not" condition
>>
>> Binding a variable to a fact in a branch of an 'or' (as you are doing 
>> with EtsExecutionOrderXref_core00) is not useful, since you cannot 
>> use this binding in the consequence. (The rule might just as well 
>> fire due to the 2nd term (the "or not...") being true, and then the 
>> variable would not be bound, causing NPE.
>>
>> If you do need this binding to access the fact in the consequence, 
>> you should splt the rule.
>>
>> -W
>>
>> 2009/12/2 Shah, Malay <Malay.Shah at morganstanley.com 
>> <mailto:Malay.Shah at morganstanley.com>>
>>
>>     Thanks Mark. I removed the binding and the rule is compiled now,
>>     but while firing the rule over set of objects, I get a Null
>>     pointer exception.
>>     Here is the updated Drool rule:
>>      
>>     dialect "mvel"
>>     rule "Legacy ETSDB Rule"
>>     when
>>            
>>     EtsExecutionOrderHist_core0:EtsExecutionOrderHist_core(customerOrFirm
>>     != "0")
>>             EtsExecutionOrderXref_core00:EtsExecutionOrderXref_core
>>             (
>>                 entityOID == EtsExecutionOrderHist_core0.entityOID,
>>                 entityRID == EtsExecutionOrderHist_core0.entityRID,
>>                 entityVID == EtsExecutionOrderHist_core0.entityVID,
>>                 referenceID != "2" && referenceIDType ==
>>     "orderSubCapacity"
>>             )
>>             or
>>             not(EtsExecutionOrderXref_core
>>                     (
>>                         entityOID ==
>>     EtsExecutionOrderHist_core0.entityOID,
>>                         entityRID ==
>>     EtsExecutionOrderHist_core0.entityRID,
>>                         entityVID ==
>>     EtsExecutionOrderHist_core0.entityVID,
>>                         referenceIDType == "orderSubCapacity"
>>                     )
>>                 )
>>     then
>>         System.out.println("Rule fired");
>>     end
>>      
>>     and here is the stack trace:
>>      
>>     Exception in thread "main"
>>     org.drools.runtime.rule.ConsequenceException:
>>     java.lang.NullPointerException
>>      at
>>     org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:23)
>>      at
>>     org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:943)
>>      at
>>     org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:885)
>>      at
>>     org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1086)
>>      at
>>     org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:660)
>>      at
>>     org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:637)
>>      at
>>     org.drools.reteoo.ReteooStatelessSession.execute(ReteooStatelessSession.java:203)
>>      at com.ms.ruleutils.RuleProcessor.process(RuleProcessor.java:142)
>>      at com.ms.ruleutils.RuleProcessor.process(RuleProcessor.java:73)
>>      at
>>     com.ms.ieddata.dataQuality.dqWithRR.DQCommandLineMain.performDQ(DQCommandLineMain.java:291)
>>      at
>>     com.ms.ieddata.dataQuality.dqWithRR.DQCommandLineMain.runEngine(DQCommandLineMain.java:196)
>>      at
>>     com.ms.ieddata.dataQuality.dqWithRR.DQCommandLineMain.main(DQCommandLineMain.java:170)
>>     Caused by: java.lang.NullPointerException
>>      at
>>     org.drools.base.mvel.DroolsMVELFactory.getTupleObjectFor(DroolsMVELFactory.java:182)
>>      at
>>     org.drools.base.mvel.DroolsMVELFactory.setContext(DroolsMVELFactory.java:176)
>>      at
>>     org.drools.base.mvel.MVELConsequence.evaluate(MVELConsequence.java:57)
>>      at
>>     org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:934)
>>      ... 10 more
>>      
>>     After debugging through, DroolMVELFactory class object is looking
>>     for Declaration definition for "EtsExecutionOrderXref_core00",
>>     not finding it, and hence giving a null pointer exception. I am
>>     using Drools 5.0.1. Any idea about why this would happen? Does
>>     the rule seem right now?
>>     Thanks
>>      
>>     Malay Shah
>>
>>      
>>     ------------------------------------------------------------------------
>>     *From:* rules-users-bounces at lists.jboss.org
>>     <mailto:rules-users-bounces at lists.jboss.org>
>>     [mailto:rules-users-bounces at lists.jboss.org
>>     <mailto:rules-users-bounces at lists.jboss.org>] *On Behalf Of *Mark
>>     Proctor
>>     *Sent:* Tuesday, December 01, 2009 6:56 PM
>>     *To:* Rules Users List
>>     *Subject:* Re: [rules-users] Drool Rule Error with "or not" condition
>>
>>     You are binding the result of the 'or' to
>>     EtsExecutionOrderXref_core00 as the second part is a 'not' which
>>     returns nothing, how would it be bound to?
>>
>>     Shah, Malay wrote:
>>>     Hi All,
>>>      
>>>     I have the following drool rule that has "or not" under Entity
>>>     Block. Basically, the rule tries to check if there either exists
>>>     an entity object EtsExecutionOrderXref_core00 with the given
>>>     conditions, or the entity does not exist at all with some other
>>>     conditions. 
>>>      
>>>     dialect "mvel"
>>>     rule "Legacy ETSDB Rule"
>>>     when
>>>     EtsExecutionOrderHist_core0:EtsExecutionOrderHist_core(customerOrFirm
>>>     != "0")
>>>     EtsExecutionOrderXref_core00:
>>>     (
>>>      EtsExecutionOrderXref_core
>>>      (
>>>       entityOID == EtsExecutionOrderHist_core0.entityOID , entityRID
>>>     == EtsExecutionOrderHist_core0.entityRID , entityVID ==
>>>     EtsExecutionOrderHist_core0.entityVID , referenceID != "2" &&
>>>     referenceIDType == "orderSubCapacity"
>>>      )
>>>      or not(EtsExecutionOrderXref_core
>>>      (
>>>       entityOID == EtsExecutionOrderHist_core0.entityOID , entityRID
>>>     == EtsExecutionOrderHist_core0.entityRID , entityVID ==
>>>     EtsExecutionOrderHist_core0.entityVID , referenceIDType ==
>>>     "orderSubCapacity"
>>>      ))
>>>     )
>>>     then
>>>     end
>>>      
>>>     But, while compiling the rule, I am getting the following errors:
>>>      
>>>     org.drools.compiler.DroolsParserException: [ERR 101] Line 22:16
>>>     no viable alternative at input 'entityOID' in rule "Legacy ETSDB
>>>     Rule" in pattern not,
>>>
>>>     org.drools.compiler.DroolsParserException: [ERR 102] Line 22:68
>>>     mismatched input ',' expecting '(' in rule "Legacy ETSDB Rule"
>>>     in pattern EtsExecutionOrderHist_core0.entityOID,
>>>
>>>     org.drools.compiler.DroolsParserException: [ERR 102] Line 22:122
>>>     mismatched input ',' expecting '(' in rule "Legacy ETSDB Rule"
>>>     in pattern EtsExecutionOrderHist_core0.entityOID in pattern
>>>     EtsExecutionOrderHist_core0.entityRID,
>>>
>>>     org.drools.compiler.DroolsParserException: [ERR 102] Line 22:176
>>>     mismatched input ',' expecting '(' in rule "Legacy ETSDB Rule"
>>>     in pattern EtsExecutionOrderHist_core0.entityOID in pattern
>>>     EtsExecutionOrderHist_core0.entityRID in pattern
>>>     EtsExecutionOrderHist_core0.entityVID]
>>>
>>>     I think the rule is correct, but am not able to figure out these
>>>     compilation errors. Could anybody please comment on why this
>>>     would happen?
>>>      
>>>     Thanks
>>>      
>>>     Malay Shah
>>>     ------------------------------------------------------------------------
>>>
>>>     NOTICE: If received in error, please destroy, and notify sender.
>>>     Sender does not intend to waive confidentiality or privilege.
>>>     Use of this email is prohibited when received in error. We may
>>>     monitor and store emails to the extent permitted by applicable law.
>>>
>>>     ------------------------------------------------------------------------
>>>
>>>     _______________________________________________
>>>     rules-users mailing list
>>>     rules-users at lists.jboss.org <mailto:rules-users at lists.jboss.org>
>>>     https://lists.jboss.org/mailman/listinfo/rules-users
>>>       
>>
>>     ------------------------------------------------------------------------
>>
>>     NOTICE: If received in error, please destroy, and notify sender.
>>     Sender does not intend to waive confidentiality or privilege. Use
>>     of this email is prohibited when received in error. We may
>>     monitor and store emails to the extent permitted by applicable law.
>>
>>
>>     _______________________________________________
>>     rules-users mailing list
>>     rules-users at lists.jboss.org <mailto:rules-users at lists.jboss.org>
>>     https://lists.jboss.org/mailman/listinfo/rules-users
>>
>>
>> ------------------------------------------------------------------------
>>
>> NOTICE: If received in error, please destroy, and notify sender. 
>> Sender does not intend to waive confidentiality or privilege. Use of 
>> this email is prohibited when received in error. We may monitor and 
>> store emails to the extent permitted by applicable law.
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> rules-users mailing list
>> rules-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>   
>
> ------------------------------------------------------------------------
>
> NOTICE: If received in error, please destroy, and notify sender. 
> Sender does not intend to waive confidentiality or privilege. Use of 
> this email is prohibited when received in error. We may monitor and 
> store emails to the extent permitted by applicable law.
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>   

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20091202/e3750c75/attachment.html 


More information about the rules-users mailing list