Details
-
Bug
-
Resolution: Done
-
Major
-
5.4.0.Final
-
None
Description
ruleflow-group + lock-on-activate may cause a ClassCastException.
import org.drools.Person; import org.drools.Cheese; rule R1 ruleflow-group "group1" lock-on-active true when $p : Person() then $p.setName("John"); update ($p); end rule R2 ruleflow-group "group1" lock-on-active true when $p : Person( name == null ) forall ( Cheese ( type == "cheddar" )) then end
Exception executing consequence for rule "R1" in defaultpkg: java.lang.ClassCastException: java.lang.Boolean cannot be cast to org.drools.spi.Activation at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39) at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1287) at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:1212) at org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1446) at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:710) at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:674) at org.drools.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:230) ... Caused by: java.lang.ClassCastException: java.lang.Boolean cannot be cast to org.drools.spi.Activation at org.drools.reteoo.RuleTerminalNode.retractLeftTuple(RuleTerminalNode.java:309) at org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateRetractLeftTuple(SingleLeftTupleSinkAdapter.java:224) at org.drools.reteoo.SingleLeftTupleSinkAdapter.propagateRetractLeftTuple(SingleLeftTupleSinkAdapter.java:98) at org.drools.reteoo.NotNode.retractLeftTuple(NotNode.java:216) at org.drools.reteoo.LeftTupleSource.doModifyLeftTuple(LeftTupleSource.java:286) at org.drools.reteoo.AbstractTerminalNode.modifyLeftTuple(AbstractTerminalNode.java:104) at org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateModifyLeftTuple(SingleLeftTupleSinkAdapter.java:205) at org.drools.reteoo.SingleLeftTupleSinkAdapter.propagateModifyObject(SingleLeftTupleSinkAdapter.java:235) at org.drools.reteoo.LeftInputAdapterNode.modifyObject(LeftInputAdapterNode.java:170) at org.drools.reteoo.CompositeObjectSinkAdapter.doPropagateModifyObject(CompositeObjectSinkAdapter.java:507) at org.drools.reteoo.CompositeObjectSinkAdapter.propagateModifyObject(CompositeObjectSinkAdapter.java:432) at org.drools.reteoo.ObjectTypeNode.modifyObject(ObjectTypeNode.java:314) at org.drools.reteoo.EntryPointNode.modifyObject(EntryPointNode.java:265) at org.drools.common.NamedEntryPoint.update(NamedEntryPoint.java:470) at org.drools.common.NamedEntryPoint.update(NamedEntryPoint.java:370) at org.drools.base.DefaultKnowledgeHelper.update(DefaultKnowledgeHelper.java:319) at defaultpkg.Rule_R1_71208af44b274026888141d4be342303.defaultConsequence(Rule_R1_71208af44b274026888141d4be342303.java:8) at defaultpkg.Rule_R1_71208af44b274026888141d4be342303DefaultConsequenceInvokerGenerated.evaluate(Unknown Source) at defaultpkg.Rule_R1_71208af44b274026888141d4be342303DefaultConsequenceInvoker.evaluate(Unknown Source) at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:1277) ... 35 more
It's probably due to the change introduced by the commit c6a3beea974234df599c4b3b80749f8ff15d3149 which sets a Boolean to the tuple.
public boolean createActivation(final LeftTuple tuple, final PropagationContext context, final InternalWorkingMemory workingMemory, final RuleTerminalNode rtn, final boolean reuseActivation ) { ... InternalAgendaGroup agendaGroup = (InternalAgendaGroup) getAgendaGroup( rule.getAgendaGroup() ); if ( rule.getRuleFlowGroup() == null ) { // No RuleFlowNode so add it directly to the Agenda // do not add the activation if the rule is "lock-on-active" and the // AgendaGroup is active if ( rule.isLockOnActive() && agendaGroup.isActive() && agendaGroup.getAutoFocusActivator() != context) { if ( tuple.getObject() == null ) { tuple.setObject( Boolean.TRUE ); // this is so we can do a check with a bit more intent than a null check on modify } return false; } } else { // There is a RuleFlowNode so add it there, instead of the Agenda InternalRuleFlowGroup rfg = (InternalRuleFlowGroup) getRuleFlowGroup( rule.getRuleFlowGroup() ); // do not add the activation if the rule is "lock-on-active" and the // RuleFlowGroup is active if ( rule.isLockOnActive() && rfg.isActive() && agendaGroup.getAutoFocusActivator() != context) { if ( tuple.getObject() == null ) { tuple.setObject( Boolean.TRUE ); // this is so we can do a check with a bit more intent than a null check on modify } return false; } }