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

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


The following commit(s) were added to refs/heads/main by this push:
     new 178cd10ff955 CAMEL-20199: Migrate context-passing ThreadLocals to 
ContextValue
178cd10ff955 is described below

commit 178cd10ff9554f7cf6deb8a090f79676af66d42d
Author: Guillaume Nodet <[email protected]>
AuthorDate: Mon Aug 3 07:46:41 2026 +0200

    CAMEL-20199: Migrate context-passing ThreadLocals to ContextValue
    
    Migrate ThreadLocal usages that pass context (Exchange, config, headers)
    during processing to ContextValue.newThreadLocal() in camel-xpath,
    camel-datasonnet, camel-jq, camel-as2, and camel-univocity-parsers.
    This is a drop-in replacement that preserves the same get()/set()/remove()
    API but will automatically switch to ScopedValue on JDK 25+, enabling
    proper virtual thread support.
    
    Closes #25242
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../java/org/apache/camel/component/as2/api/AS2ServerConnection.java | 4 +++-
 .../src/main/java/org/apache/camel/language/datasonnet/CML.java      | 5 +++--
 .../src/main/java/org/apache/camel/language/jq/JqFunctions.java      | 3 ++-
 .../org/apache/camel/dataformat/univocity/HeaderRowProcessor.java    | 3 ++-
 .../org/apache/camel/language/xpath/MessageVariableResolver.java     | 5 +++--
 .../src/main/java/org/apache/camel/language/xpath/XPathBuilder.java  | 3 ++-
 6 files changed, 15 insertions(+), 8 deletions(-)

diff --git 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
index ac0d565f329d..e99112afc581 100644
--- 
a/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
+++ 
b/components/camel-as2/camel-as2-api/src/main/java/org/apache/camel/component/as2/api/AS2ServerConnection.java
@@ -42,6 +42,7 @@ import 
org.apache.camel.component.as2.api.entity.MultipartSignedEntity;
 import org.apache.camel.component.as2.api.io.AS2BHttpServerConnection;
 import org.apache.camel.component.as2.api.protocol.ResponseMDN;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.concurrent.ContextValue;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.EntityDetails;
@@ -124,7 +125,8 @@ public class AS2ServerConnection {
      * Stores the request-specific AS2ConsumerConfiguration and path. Used for 
post-processing logic (like asynchronous
      * MDN) after the main HttpService handling is complete.
      */
-    private static final ThreadLocal<ThreadLocalConfigWrapper> 
CURRENT_CONSUMER_CONFIG = new ThreadLocal<>();
+    private static final ContextValue<ThreadLocalConfigWrapper> 
CURRENT_CONSUMER_CONFIG
+            = ContextValue.newThreadLocal("AS2ConsumerConfig");
 
     /**
      * Configuration data holding all necessary security material (signing 
keys/certs and decryption keys/certs) for a
diff --git 
a/components/camel-datasonnet/src/main/java/org/apache/camel/language/datasonnet/CML.java
 
b/components/camel-datasonnet/src/main/java/org/apache/camel/language/datasonnet/CML.java
index 3d82d5986919..3058ecd95e23 100644
--- 
a/components/camel-datasonnet/src/main/java/org/apache/camel/language/datasonnet/CML.java
+++ 
b/components/camel-datasonnet/src/main/java/org/apache/camel/language/datasonnet/CML.java
@@ -42,10 +42,11 @@ import com.datasonnet.spi.DataFormatService;
 import com.datasonnet.spi.Library;
 import com.datasonnet.spi.PluginException;
 import org.apache.camel.Exchange;
+import org.apache.camel.util.concurrent.ContextValue;
 
 public final class CML extends Library {
     private static final CML INSTANCE = new CML();
-    private final ThreadLocal<Exchange> exchange = new ThreadLocal<>();
+    private final ContextValue<Exchange> exchange = 
ContextValue.newThreadLocal("DataSonnetExchange");
 
     private CML() {
     }
@@ -54,7 +55,7 @@ public final class CML extends Library {
         return INSTANCE;
     }
 
-    public ThreadLocal<Exchange> getExchange() {
+    public ContextValue<Exchange> getExchange() {
         return exchange;
     }
 
diff --git 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
index 1022447b1367..a0fa85ed33a7 100644
--- 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
+++ 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
@@ -35,12 +35,13 @@ import net.thisptr.jackson.jq.path.Path;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.StreamCache;
+import org.apache.camel.util.concurrent.ContextValue;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public final class JqFunctions {
 
-    public static final ThreadLocal<Exchange> EXCHANGE_LOCAL = new 
ThreadLocal<>();
+    public static final ContextValue<Exchange> EXCHANGE_LOCAL = 
ContextValue.newThreadLocal("JqExchange");
 
     private static final Logger LOGGER = 
LoggerFactory.getLogger(JqFunctions.class);
 
diff --git 
a/components/camel-univocity-parsers/src/main/java/org/apache/camel/dataformat/univocity/HeaderRowProcessor.java
 
b/components/camel-univocity-parsers/src/main/java/org/apache/camel/dataformat/univocity/HeaderRowProcessor.java
index 2b4ee4b06dbf..f4430ad68efd 100644
--- 
a/components/camel-univocity-parsers/src/main/java/org/apache/camel/dataformat/univocity/HeaderRowProcessor.java
+++ 
b/components/camel-univocity-parsers/src/main/java/org/apache/camel/dataformat/univocity/HeaderRowProcessor.java
@@ -18,12 +18,13 @@ package org.apache.camel.dataformat.univocity;
 
 import com.univocity.parsers.common.ParsingContext;
 import com.univocity.parsers.common.processor.RowProcessor;
+import org.apache.camel.util.concurrent.ContextValue;
 
 /**
  * This class is used by the unmarshaller in order to retrieve the headers.
  */
 final class HeaderRowProcessor implements RowProcessor {
-    private final static ThreadLocal<String[]> headers = new ThreadLocal<>();
+    private static final ContextValue<String[]> headers = 
ContextValue.newThreadLocal("UnivocityHeaders");
 
     /**
      * Called when the processing starts, it clears the headers
diff --git 
a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/MessageVariableResolver.java
 
b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/MessageVariableResolver.java
index ec43edcffdfd..a713a8aaf264 100644
--- 
a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/MessageVariableResolver.java
+++ 
b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/MessageVariableResolver.java
@@ -24,6 +24,7 @@ import javax.xml.xpath.XPathVariableResolver;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
+import org.apache.camel.util.concurrent.ContextValue;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,9 +44,9 @@ public class MessageVariableResolver implements 
XPathVariableResolver {
     private static final Logger LOG = 
LoggerFactory.getLogger(MessageVariableResolver.class);
 
     private Map<String, Object> variables = new HashMap<>();
-    private final ThreadLocal<Exchange> exchange;
+    private final ContextValue<Exchange> exchange;
 
-    public MessageVariableResolver(ThreadLocal<Exchange> exchange) {
+    public MessageVariableResolver(ContextValue<Exchange> exchange) {
         this.exchange = exchange;
     }
 
diff --git 
a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
 
b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
index 80f9ebfe30d3..da44704e201a 100644
--- 
a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
+++ 
b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
@@ -70,6 +70,7 @@ import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.concurrent.ContextValue;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -105,7 +106,7 @@ public class XPathBuilder extends ServiceSupport
     private final Queue<XPathExpression> pool = new ConcurrentLinkedQueue<>();
     private final Queue<XPathExpression> poolLogNamespaces = new 
ConcurrentLinkedQueue<>();
     private final String text;
-    private final ThreadLocal<Exchange> exchange = new ThreadLocal<>();
+    private final ContextValue<Exchange> exchange = 
ContextValue.newThreadLocal("XPathExchange");
     private final MessageVariableResolver variableResolver = new 
MessageVariableResolver(exchange);
     private final Map<String, String> namespaces = new ConcurrentHashMap<>();
     private boolean preCompile = true;

Reply via email to