This is an automated email from the ASF dual-hosted git repository.
tkobayas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie.git
The following commit(s) were added to refs/heads/main by this push:
new c706a6993b2 [incubator-kie#7188] fix(drools): ClassCastException in
doSubnetwork2 when a subnetwork is shared by not() and accumulate() (#7191)
c706a6993b2 is described below
commit c706a6993b22b1ea9a17e903a5c77321b0617ffc
Author: salome522 <[email protected]>
AuthorDate: Thu Oct 15 07:29:39 2026 +0200
[incubator-kie#7188] fix(drools): ClassCastException in doSubnetwork2 when
a subnetwork is shared by not() and accumulate() (#7191)
When a subnetwork is shared, doSubnetwork2 collects the memory of every
sink. For the second and following sinks it checked the type of the first
sink instead of the current one, so a NotNode/ExistsNode (BetaMemory) and
an AccumulateNode (AccumulateMemory) sharing one subnetwork led to a
ClassCastException in either direction, depending on the rule order.
The regression test in SubnetworkTest covers both rule orders, with and
without a matching tuple, and fails without the fix.
Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
.../core/phreak/RuleNetworkEvaluatorImpl.java | 2 +-
.../compiler/integrationtests/SubnetworkTest.java | 64 ++++++++++++++++++++++
2 files changed, 65 insertions(+), 1 deletion(-)
diff --git
a/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluatorImpl.java
b/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluatorImpl.java
index 9e6c2b6eb32..b73e27f09d8 100644
---
a/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluatorImpl.java
+++
b/drools-core/src/main/java/org/drools/core/phreak/RuleNetworkEvaluatorImpl.java
@@ -603,7 +603,7 @@ public class RuleNetworkEvaluatorImpl implements
RuleNetworkEvaluator {
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()) {
+ if (NodeTypeEnums.AccumulateNode == bns[i - 1].getType()) {
bms[i - 1] = ((AccumulateMemory) nodeMem2).getBetaMemory();
} else {
bms[i - 1] = (BetaMemory) nodeMem2;
diff --git
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/SubnetworkTest.java
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/SubnetworkTest.java
index e26348869af..84b9a333a4a 100644
---
a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/SubnetworkTest.java
+++
b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/compiler/integrationtests/SubnetworkTest.java
@@ -521,4 +521,68 @@ public class SubnetworkTest {
kieSession.dispose();
}
}
+
+ @ParameterizedTest(name = "KieBase type={0}")
+ @MethodSource("parameters")
+ public void
subnetworkSharedByNotAndAccumulate_notRuleFirst_shouldNotThrowClassCastException(KieBaseTestConfiguration
kieBaseTestConfiguration) {
+ // incubator-kie#7188
+ testSubnetworkSharedByNotAndAccumulate(kieBaseTestConfiguration, true);
+ }
+
+ @ParameterizedTest(name = "KieBase type={0}")
+ @MethodSource("parameters")
+ public void
subnetworkSharedByNotAndAccumulate_accumulateRuleFirst_shouldNotThrowClassCastException(KieBaseTestConfiguration
kieBaseTestConfiguration) {
+ // incubator-kie#7188
+ testSubnetworkSharedByNotAndAccumulate(kieBaseTestConfiguration,
false);
+ }
+
+ private void
testSubnetworkSharedByNotAndAccumulate(KieBaseTestConfiguration
kieBaseTestConfiguration, boolean notRuleFirst) {
+ final String notRule =
+ "rule NotRule when\n" +
+ " not( X( $id : id ) and $y : Y( parentId == $id ) )\n" +
+ "then\n" +
+ " list.add(\"NotRule\");\n" +
+ "end\n";
+ final String accumulateRule =
+ "rule AccumulateRule when\n" +
+ " accumulate( X( $id : id ) and $y : Y( parentId == $id );
$count : count($y) )\n" +
+ "then\n" +
+ " list.add(\"AccumulateRule \" + $count);\n" +
+ "end\n";
+ final String drl =
+ "import " + X.class.getCanonicalName() + "\n" +
+ "import " + Y.class.getCanonicalName() + "\n" +
+ "global java.util.List list\n" +
+ (notRuleFirst ? notRule + accumulateRule : accumulateRule +
notRule);
+
+ final KieBase kbase =
KieBaseUtil.getKieBaseFromKieModuleFromDrl("subnetwork-test",
kieBaseTestConfiguration, drl);
+
+ final KieSession withoutMatchSession = kbase.newKieSession();
+ try {
+ final List<String> list = new ArrayList<>();
+ withoutMatchSession.setGlobal("list", list);
+ withoutMatchSession.insert(new X(1));
+ withoutMatchSession.insert(new Y(2));
+
+ withoutMatchSession.fireAllRules();
+
+ assertThat(list).containsExactlyInAnyOrder("NotRule",
"AccumulateRule 0");
+ } finally {
+ withoutMatchSession.dispose();
+ }
+
+ final KieSession withMatchSession = kbase.newKieSession();
+ try {
+ final List<String> list = new ArrayList<>();
+ withMatchSession.setGlobal("list", list);
+ withMatchSession.insert(new X(1));
+ withMatchSession.insert(new Y(1));
+
+ withMatchSession.fireAllRules();
+
+ assertThat(list).containsExactly("AccumulateRule 1");
+ } finally {
+ withMatchSession.dispose();
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]