This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch pc
in repository https://gitbox.apache.org/repos/asf/camel.git

commit ac57a7cc7bbab381d87d5f78e573354f71dfaf1c
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Feb 8 11:28:28 2026 +0100

    CAMEL-22973: camel-core - ClassCastException in Splitter with exchange 
pooling
---
 .../camel/processor/PooledExchangeSplitTest.java   | 72 ++++++++++++++++++++++
 .../org/apache/camel/support/DefaultExchange.java  |  6 +-
 .../org/apache/camel/support/MonotonicClock.java   |  2 +
 .../org/apache/camel/support/ResetableClock.java   |  4 +-
 4 files changed, 80 insertions(+), 4 deletions(-)

diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/PooledExchangeSplitTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/PooledExchangeSplitTest.java
new file mode 100644
index 000000000000..da724d73fb6e
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/PooledExchangeSplitTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.engine.PooledExchangeFactory;
+import org.apache.camel.impl.engine.PooledProcessorExchangeFactory;
+import org.junit.jupiter.api.Test;
+
+class PooledExchangeSplitTest extends ContextTestSupport {
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext camelContext = super.createCamelContext();
+        ExtendedCamelContext ecc = camelContext.getCamelContextExtension();
+
+        ecc.setExchangeFactory(new PooledExchangeFactory());
+
+        ecc.setProcessorExchangeFactory(new PooledProcessorExchangeFactory());
+        ecc.getExchangeFactory().setStatisticsEnabled(true);
+        ecc.getProcessorExchangeFactory().setStatisticsEnabled(true);
+
+        return camelContext;
+    }
+
+    @Test
+    public void testSplitter() throws Exception {
+        List<Integer> data = new ArrayList<>(Arrays.asList(1, 2, 3));
+
+        getMockEndpoint("mock:result").expectedMessageCount(3);
+
+        template.sendBody("direct:processData", data);
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:processData")
+                        .split(body()).streaming().parallelProcessing()
+                        .to("mock:result");
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultExchange.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultExchange.java
index cb4d4728fc34..c232ae712e02 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultExchange.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultExchange.java
@@ -36,17 +36,17 @@ public final class DefaultExchange extends AbstractExchange 
{
     DefaultExchange(CamelContext context, EnumMap<ExchangePropertyKey, Object> 
internalProperties,
                     Map<String, Object> properties) {
         super(context, internalProperties, properties);
-        this.timeInfo = new MonotonicClock();
+        this.timeInfo = new ResetableClock();
     }
 
     public DefaultExchange(CamelContext context) {
         super(context);
-        this.timeInfo = new MonotonicClock();
+        this.timeInfo = new ResetableClock();
     }
 
     public DefaultExchange(CamelContext context, ExchangePattern pattern) {
         super(context, pattern);
-        this.timeInfo = new MonotonicClock();
+        this.timeInfo = new ResetableClock();
     }
 
     public DefaultExchange(Exchange parent) {
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/MonotonicClock.java 
b/core/camel-support/src/main/java/org/apache/camel/support/MonotonicClock.java
index 46ab3772368c..01ab4f8beb89 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/MonotonicClock.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/MonotonicClock.java
@@ -22,6 +22,8 @@ import org.apache.camel.clock.Clock;
 
 /**
  * A clock that increases monotonically (i.e.: does not go back in time) for 
precise elapsed calculations.
+ *
+ * @see ResetableClock
  */
 public final class MonotonicClock implements Clock {
     private final long created;
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/ResetableClock.java 
b/core/camel-support/src/main/java/org/apache/camel/support/ResetableClock.java
index 00091ac8353c..c9b5609aa4d1 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/ResetableClock.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/ResetableClock.java
@@ -21,7 +21,9 @@ import java.util.concurrent.TimeUnit;
 import org.apache.camel.clock.Clock;
 
 /**
- * A clock that can be reset.
+ * A clock for precises elapsed calculations, that also can be reset.
+ *
+ * @see MonotonicClock
  */
 public final class ResetableClock implements Clock {
     private long created;

Reply via email to