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

gnodet pushed a commit to branch camel-22090-couchbase-jackson
in repository https://gitbox.apache.org/repos/asf/camel.git

commit c45f8ab762aefc9bb7af1bd7d3a5620956f1cdce
Author: Guillaume Nodet <[email protected]>
AuthorDate: Fri Mar 13 08:30:23 2026 +0100

    CAMEL-22090: Fix couchbase consumer when Jackson is on classpath
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../component/couchbase/CouchbaseConsumer.java     |  7 +++--
 .../component/couchbase/CouchbaseEndpoint.java     | 33 ++++++++++++++++------
 .../component/couchbase/CouchbaseEndpointTest.java | 26 +++++++++++++++++
 3 files changed, 55 insertions(+), 11 deletions(-)

diff --git 
a/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseConsumer.java
 
b/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseConsumer.java
index 8453d71ca817..1499f16e873b 100644
--- 
a/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseConsumer.java
+++ 
b/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseConsumer.java
@@ -21,7 +21,6 @@ import java.util.Queue;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
-import com.couchbase.client.core.deps.com.fasterxml.jackson.databind.JsonNode;
 import com.couchbase.client.java.Bucket;
 import com.couchbase.client.java.Collection;
 import com.couchbase.client.java.Scope;
@@ -143,7 +142,11 @@ public class CouchbaseConsumer extends 
ScheduledBatchPollingConsumer implements
                     doc = row.valueAs(Object.class);
                 }
 
-                String key = row.keyAs(JsonNode.class).get().asText();
+                // Use String.class instead of the shaded JsonNode class to 
avoid conflicts
+                // when Jackson is on the classpath (CAMEL-22090). The 
Couchbase SDK's
+                // auto-detection of non-shaded Jackson would otherwise cause 
deserialization
+                // failures when trying to deserialize into the shaded 
JsonNode class.
+                String key = row.keyAs(String.class).orElse(null);
                 String designDocumentName = endpoint.getDesignDocumentName();
                 String viewName = endpoint.getViewName();
 
diff --git 
a/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseEndpoint.java
 
b/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseEndpoint.java
index d38b5a3d9f5d..989a43da501d 100644
--- 
a/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseEndpoint.java
+++ 
b/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseEndpoint.java
@@ -561,15 +561,7 @@ public class CouchbaseEndpoint extends 
ScheduledPollEndpoint implements Endpoint
             throw new CamelException(COUCHBASE_URI_ERROR);
         }
 
-        ClusterEnvironment.Builder cfb = ClusterEnvironment.builder();
-        cfb.jsonSerializer(DefaultJsonSerializer.create());
-        if (queryTimeout != DEFAULT_QUERY_TIMEOUT) {
-            cfb.timeoutConfig()
-                    .connectTimeout(Duration.ofMillis(connectTimeout))
-                    .queryTimeout(Duration.ofMillis(queryTimeout));
-        }
-
-        ClusterEnvironment env = cfb.build();
+        ClusterEnvironment env = createClusterEnvironment();
 
         String addHosts = hosts.stream()
                 .map(URI::getHost)
@@ -588,6 +580,29 @@ public class CouchbaseEndpoint extends 
ScheduledPollEndpoint implements Endpoint
         return cluster.bucket(bucket);
     }
 
+    /**
+     * Creates the {@link ClusterEnvironment} for connecting to Couchbase.
+     * <p>
+     * Explicitly configures the {@link DefaultJsonSerializer} to prevent the 
Couchbase SDK from auto-detecting Jackson
+     * on the classpath (CAMEL-22090). Without this, when a non-shaded Jackson 
library is present (e.g., via
+     * camel-jackson, Spring Boot, or Quarkus), the SDK would use {@code 
JacksonJsonSerializer} backed by the non-shaded
+     * Jackson {@code ObjectMapper}. This causes deserialization failures 
because the SDK's internal types (such as view
+     * row keys) rely on the shaded Jackson classes bundled within the 
Couchbase SDK.
+     * <p>
+     * The {@link DefaultJsonSerializer} uses the shaded Jackson {@code 
ObjectMapper} bundled inside the Couchbase SDK,
+     * ensuring consistent serialization/deserialization regardless of what 
other Jackson versions are on the classpath.
+     */
+    ClusterEnvironment createClusterEnvironment() {
+        ClusterEnvironment.Builder cfb = ClusterEnvironment.builder();
+        cfb.jsonSerializer(DefaultJsonSerializer.create());
+        if (queryTimeout != DEFAULT_QUERY_TIMEOUT) {
+            cfb.timeoutConfig()
+                    .connectTimeout(Duration.ofMillis(connectTimeout))
+                    .queryTimeout(Duration.ofMillis(queryTimeout));
+        }
+        return cfb.build();
+    }
+
     /**
      * Compares retry strategy with query timeout and gets the higher value : 
for write operations with retry
      *
diff --git 
a/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/CouchbaseEndpointTest.java
 
b/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/CouchbaseEndpointTest.java
index bf050e20bd92..c614e6c3726d 100644
--- 
a/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/CouchbaseEndpointTest.java
+++ 
b/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/CouchbaseEndpointTest.java
@@ -19,6 +19,9 @@ package org.apache.camel.component.couchbase;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.couchbase.client.java.codec.DefaultJsonSerializer;
+import com.couchbase.client.java.codec.JsonSerializer;
+import com.couchbase.client.java.env.ClusterEnvironment;
 import org.apache.camel.Processor;
 import org.junit.jupiter.api.Test;
 
@@ -169,4 +172,27 @@ public class CouchbaseEndpointTest {
 
         endpoint.setDescending(false);
     }
+
+    /**
+     * Verifies that the ClusterEnvironment is configured with 
DefaultJsonSerializer to prevent the Couchbase SDK from
+     * auto-detecting non-shaded Jackson on the classpath (CAMEL-22090). When 
non-shaded Jackson is present (e.g., via
+     * camel-jackson, Spring Boot, or Quarkus), auto-detection would cause the 
SDK to use JacksonJsonSerializer, leading
+     * to deserialization failures for SDK internal types that depend on 
shaded Jackson classes.
+     */
+    @Test
+    public void testClusterEnvironmentUsesDefaultJsonSerializer() {
+        CouchbaseEndpoint endpoint = new CouchbaseEndpoint();
+        ClusterEnvironment env = endpoint.createClusterEnvironment();
+        try {
+            JsonSerializer serializer = env.jsonSerializer();
+            // The serializer must not be JacksonJsonSerializer since that 
would fail
+            // when a non-shaded Jackson is on the classpath. It should be 
wrapped in
+            // JsonValueSerializerWrapper which delegates to 
DefaultJsonSerializer.
+            
assertEquals("com.couchbase.client.java.codec.JsonValueSerializerWrapper",
+                    serializer.getClass().getName(),
+                    "ClusterEnvironment should wrap DefaultJsonSerializer in 
JsonValueSerializerWrapper");
+        } finally {
+            env.shutdown();
+        }
+    }
 }

Reply via email to