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?
Thanks
Malay Shah
________________________________
From: rules-users-bounces(a)lists.jboss.org [mailto:rules-users-bounces@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@lists.jboss.org<mailto:rules-users-bounces@lists.jboss.org>
[mailto:rules-users-bounces@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@morganstanley.com<mailto:Malay.Shah@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@lists.jboss.org<mailto:rules-users-bounces@lists.jboss.org>
[mailto:rules-users-bounces@lists.jboss.org<mailto:rules-users-bounces@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@lists.jboss.org<mailto:rules-users@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@lists.jboss.org<mailto:rules-users@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@lists.jboss.org<mailto:rules-users@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.