diff --git a/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/CxfTimeoutTest.java b/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/CxfTimeoutTest.java
index 0762cec094262..80256ef456850 100644
--- a/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/CxfTimeoutTest.java
+++ b/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/CxfTimeoutTest.java
@@ -45,6 +45,13 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+/**
+ * Tests CXF ReceiveTimeout behavior. The timeout is configured to 100ms in cxfConduitTimeOutContext.xml via a wildcard
+ * http-conduit. However, the JAX-WS server published in {@code @BeforeAll} creates a default CXF Bus without that
+ * configuration. Under CI load, the client conduit can sometimes resolve against the wrong Bus and miss the 100ms
+ * timeout entirely. To make the timeout reliable, each timeout-expecting test method uses {@code TimeoutCxfConfigurer}
+ * to explicitly set the ReceiveTimeout on the conduit, independent of Bus-level configuration.
+ */
@Isolated
public class CxfTimeoutTest extends CamelSpringTestSupport {
@@ -61,17 +68,21 @@ public static void startService() {
@Test
public void testInvokingJaxWsServerWithBusUriParams() throws Exception {
- sendTimeOutMessage("cxf://" + JAXWS_SERVER_ADDRESS + "?serviceClass=org.apache.hello_world_soap_http.Greeter&bus=#cxf");
+ sendTimeOutMessage(
+ "cxf://" + JAXWS_SERVER_ADDRESS
+ + "?serviceClass=org.apache.hello_world_soap_http.Greeter&bus=#cxf&cxfConfigurer=#timeoutConfigurer");
}
@Test
public void testInvokingJaxWsServerWithoutBusUriParams() throws Exception {
- sendTimeOutMessage("cxf://" + JAXWS_SERVER_ADDRESS + "?serviceClass=org.apache.hello_world_soap_http.Greeter");
+ sendTimeOutMessage(
+ "cxf://" + JAXWS_SERVER_ADDRESS
+ + "?serviceClass=org.apache.hello_world_soap_http.Greeter&cxfConfigurer=#timeoutConfigurer");
}
@Test
public void testInvokingJaxWsServerWithCxfEndpoint() throws Exception {
- sendTimeOutMessage("cxf://bean:springEndpoint");
+ sendTimeOutMessage("cxf://bean:springEndpoint?cxfConfigurer=#timeoutConfigurer");
}
@Test
@@ -117,6 +128,31 @@ protected AbstractXmlApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("org/apache/camel/component/cxf/cxfConduitTimeOutContext.xml");
}
+ /**
+ * Explicitly sets the 100ms ReceiveTimeout on the conduit so that the timeout is applied regardless of which CXF
+ * Bus the conduit was created from.
+ */
+ public static class TimeoutCxfConfigurer implements CxfConfigurer {
+
+ @Override
+ public void configure(AbstractWSDLBasedEndpointFactory factoryBean) {
+ // Do nothing here
+ }
+
+ @Override
+ public void configureClient(Client client) {
+ HTTPConduit conduit = (HTTPConduit) client.getConduit();
+ HTTPClientPolicy policy = new HTTPClientPolicy();
+ policy.setReceiveTimeout(100);
+ conduit.setClient(policy);
+ }
+
+ @Override
+ public void configureServer(Server server) {
+ // Do nothing here
+ }
+ }
+
public static class MyCxfConfigurer implements CxfConfigurer {
@Override
diff --git a/components/camel-cxf/camel-cxf-spring-soap/src/test/resources/org/apache/camel/component/cxf/cxfConduitTimeOutContext.xml b/components/camel-cxf/camel-cxf-spring-soap/src/test/resources/org/apache/camel/component/cxf/cxfConduitTimeOutContext.xml
index 21f3b68fd260c..7e55def1f8d9a 100644
--- a/components/camel-cxf/camel-cxf-spring-soap/src/test/resources/org/apache/camel/component/cxf/cxfConduitTimeOutContext.xml
+++ b/components/camel-cxf/camel-cxf-spring-soap/src/test/resources/org/apache/camel/component/cxf/cxfConduitTimeOutContext.xml
@@ -46,7 +46,12 @@
-
+
+
+
+
@@ -58,12 +63,12 @@
-
+
-
+
diff --git a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
index 5c56dcb29ce17..55b2a562a9702 100644
--- a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
+++ b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
@@ -23,6 +23,7 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.Isolated;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
@@ -37,6 +38,9 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+// Run in isolation to prevent JMX MBean name collisions with concurrent
+// test classes that create CamelContexts with the same management name
+@Isolated
public class SpringQuartzPersistentStoreRestartAppChangeOptionsTest {
private static AbstractXmlApplicationContext db;
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java
index 059388f860d5e..75a3683e3b3de 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java
@@ -62,8 +62,12 @@ public class BacklogTracer extends ServiceSupport implements org.apache.camel.sp
public static final int MAX_BACKLOG_SIZE = 1000;
private final CamelContext camelContext;
private final Language simple;
- private boolean enabled;
- private boolean standby;
+ // These three flags are toggled at runtime via JMX/management APIs while routing
+ // threads read them in shouldTrace() and traceEvent(). Other boolean fields (removeOnDump,
+ // bodyIncludeStreams, traceRests, etc.) are set during initialization and do not change
+ // while routes are processing, so they do not need volatile.
+ private volatile boolean enabled;
+ private volatile boolean standby;
private final AtomicLong traceCounter = new AtomicLong();
// use a queue with an upper limit to avoid storing too many messages
private final Queue queue = new LinkedBlockingQueue<>(MAX_BACKLOG_SIZE);
@@ -87,7 +91,7 @@ public class BacklogTracer extends ServiceSupport implements org.apache.camel.sp
private boolean includeExchangeProperties = true;
private boolean includeExchangeVariables = true;
private boolean includeException = true;
- private boolean activityEnabled;
+ private volatile boolean activityEnabled;
private boolean traceRests;
private boolean traceTemplates;
// a pattern to filter tracing nodes