salome522 opened a new issue, #7188:
URL: https://github.com/apache/incubator-kie/issues/7188
### Describe the bug
`fireAllRules()` throws a `ClassCastException` in
`RuleNetworkEvaluatorImpl.doSubnetwork2` when the same multi-pattern group is
used inside `not( ... )` in one rule and as the source of `accumulate( ... )`
in another rule of the same KieBase. Each rule works on its own. The KieBase
builds without errors; the exception only occurs at runtime, and it aborts the
whole `fireAllRules()`.
#### Trigger conditions
- Two rules in the same KieBase contain an identical group of two or more
patterns (same patterns, same order, same constraints), so the subnetwork is
shared.
- One rule uses the group inside `not( ... )`, the other as the source of
`accumulate( ... )`.
- The rule order decides which cast fails:
- `not` rule first: `AccumulateNode$SingleAccumulateMemory cannot be cast
to BetaMemory`
- `accumulate` rule first: `BetaMemory cannot be cast to
AccumulateNode$AccumulateMemory`
#### Root cause
In `RuleNetworkEvaluatorImpl.doSubnetwork2`, the loop that collects the
memories of the second and following sinks checks the type of the **first**
sink (`betaNode`) instead of the current one (`bns[i - 1]`):
```java
for (int i = 1; i < length; i++) {
bns[i - 1] = ((RightInputAdapterNode)sinks[i]).getBetaNode();
Memory nodeMem2 = nodeMemories.getNodeMemory(bns[i - 1]);
if (NodeTypeEnums.AccumulateNode == betaNode.getType()) { // should be
bns[i - 1].getType()
bms[i - 1] = ((AccumulateMemory) nodeMem2).getBetaMemory();
} else {
bms[i - 1] = (BetaMemory) nodeMem2;
}
}
```
So the code only works when all sinks of a shared subnetwork have the same
memory type. `not()` + `exists()` (both `BetaMemory`) works; `exists()` +
`accumulate()` fails the same way as `not()` + `accumulate()`, in both rule
orders.
### Expected behavior
Both rules are evaluated normally. Whether the subnetwork is shared or not
should make no difference to the result.
### Actual behavior
```
java.lang.ClassCastException: class
org.drools.core.reteoo.AccumulateNode$SingleAccumulateMemory cannot be cast to
class org.drools.core.reteoo.BetaMemory
at
org.drools.core.phreak.RuleNetworkEvaluatorImpl.doSubnetwork2(RuleNetworkEvaluatorImpl.java:609)
at org.drools.core.phreak.RuleNetworkEvaluatorImpl.evaluateEndNode(...)
at org.drools.core.phreak.RuleNetworkEvaluatorImpl.innerEval(...)
at org.drools.core.phreak.RuleNetworkEvaluatorImpl.doSubnetwork(...)
at org.drools.core.phreak.RuleNetworkEvaluatorImpl.evaluateBetaNode(...)
...
at
org.drools.kiesession.session.StatefulKnowledgeSessionImpl.fireAllRules(...)
```
With the two rules in the opposite order, the reverse cast fails at line 607
(`BetaMemory cannot be cast to AccumulateNode$AccumulateMemory`). Line numbers
are from `main`; on 10.2.0 they are 599 and 597.
### How to Reproduce?
Deterministic, fails on every run:
```
declare Trigger key: int end
declare A key: int d: int end
declare B key: int d: int end
rule "setup" salience 100 when then
insert( new Trigger( 1 ) ); insert( new A( 1, 1 ) ); insert( new B( 1, 2 )
);
end
rule "group under not" when
Trigger( $k: key )
not( A( key == $k, $d: d ) and B( key == $k, d == $d ) )
then end
rule "same group as accumulate source" when
Trigger( $k: key )
accumulate( A( key == $k, $d: d ) and B( key == $k, d == $d ); $s:
collectSet( $d ) )
then end
```
Expected: 3 firings. Actual: `ClassCastException`.
- Each rule alone works.
- Reversing the patterns in one group (`not( B(...) and A(...) )`) avoids
the crash, because the groups are no longer shared.
- `enabled false` on one rule does not help.
### Output of `uname -a` or `ver`
_No response_
### Output of `java -version`
_No response_
### GraalVM version (if different from Java)
_No response_
### Kogito version or git rev (or at least Quarkus version if you are using
Kogito via Quarkus platform BOM)
Drools 10.2.0, and main at a0899a7d1c2
### Build tool (ie. output of `mvnw --version` or `gradlew --version`)
_No response_
### Additional information
The wrong check predates the 2025 move of this code into
`RuleNetworkEvaluatorImpl` (it was already present in 2013), so this is not
caused by recent changes.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]