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

davsclaus pushed a commit to branch fix/CAMEL-24163
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 09e708e1cdbdbd7a310319c7c5c98944ee0f12ea
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jul 17 13:14:33 2026 +0200

    CAMEL-24163: Guard Jackson-only options in JsonDataFormatReifier to not 
crash non-Jackson libraries
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../fastjson/FastjsonDataFormatConfigurer.java     |  7 ++
 .../apache/camel/component/fastjson/fastjson.json  |  5 +-
 .../component/fastjson/FastjsonDataFormat.java     |  2 +-
 .../reifier/dataformat/JsonDataFormatReifier.java  | 35 ++++----
 .../dataformat/JsonDataFormatReifierTest.java      | 96 ++++++++++++++++++++++
 5 files changed, 125 insertions(+), 20 deletions(-)

diff --git 
a/components/camel-fastjson/src/generated/java/org/apache/camel/component/fastjson/FastjsonDataFormatConfigurer.java
 
b/components/camel-fastjson/src/generated/java/org/apache/camel/component/fastjson/FastjsonDataFormatConfigurer.java
index 54cd153bcbb7..fcb4bbe1602c 100644
--- 
a/components/camel-fastjson/src/generated/java/org/apache/camel/component/fastjson/FastjsonDataFormatConfigurer.java
+++ 
b/components/camel-fastjson/src/generated/java/org/apache/camel/component/fastjson/FastjsonDataFormatConfigurer.java
@@ -23,6 +23,7 @@ public class FastjsonDataFormatConfigurer extends 
org.apache.camel.support.compo
     static {
         Map<String, Object> map = new CaseInsensitiveMap();
         map.put("ContentTypeHeader", boolean.class);
+        map.put("PrettyPrint", boolean.class);
         map.put("UnmarshalType", java.lang.Class.class);
         ALL_OPTIONS = map;
     }
@@ -33,6 +34,8 @@ public class FastjsonDataFormatConfigurer extends 
org.apache.camel.support.compo
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "contenttypeheader":
         case "contentTypeHeader": 
target.setContentTypeHeader(property(camelContext, boolean.class, value)); 
return true;
+        case "prettyprint":
+        case "prettyPrint": target.setPrettyPrint(property(camelContext, 
boolean.class, value)); return true;
         case "unmarshaltype":
         case "unmarshalType": target.setUnmarshalType(property(camelContext, 
java.lang.Class.class, value)); return true;
         default: return false;
@@ -49,6 +52,8 @@ public class FastjsonDataFormatConfigurer extends 
org.apache.camel.support.compo
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "contenttypeheader":
         case "contentTypeHeader": return boolean.class;
+        case "prettyprint":
+        case "prettyPrint": return boolean.class;
         case "unmarshaltype":
         case "unmarshalType": return java.lang.Class.class;
         default: return null;
@@ -61,6 +66,8 @@ public class FastjsonDataFormatConfigurer extends 
org.apache.camel.support.compo
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "contenttypeheader":
         case "contentTypeHeader": return target.isContentTypeHeader();
+        case "prettyprint":
+        case "prettyPrint": return target.isPrettyPrint();
         case "unmarshaltype":
         case "unmarshalType": return target.getUnmarshalType();
         default: return null;
diff --git 
a/components/camel-fastjson/src/generated/resources/META-INF/org/apache/camel/component/fastjson/fastjson.json
 
b/components/camel-fastjson/src/generated/resources/META-INF/org/apache/camel/component/fastjson/fastjson.json
index 56e9bdd1f8d9..d87a6f0ba1ac 100644
--- 
a/components/camel-fastjson/src/generated/resources/META-INF/org/apache/camel/component/fastjson/fastjson.json
+++ 
b/components/camel-fastjson/src/generated/resources/META-INF/org/apache/camel/component/fastjson/fastjson.json
@@ -16,7 +16,8 @@
     "modelJavaType": "org.apache.camel.model.dataformat.JsonDataFormat"
   },
   "properties": {
-    "unmarshalType": { "index": 0, "kind": "attribute", "displayName": 
"Unmarshal Type", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Class name of the java type to use when 
unmarshalling." },
-    "contentTypeHeader": { "index": 1, "kind": "attribute", "displayName": 
"Content Type Header", "group": "common", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether the data format 
should set the Content-Type header with the type from the data format. For 
example application\/xml for data formats marshalling to XML, or 
application\/json for data formats marshalli [...]
+    "prettyPrint": { "index": 0, "kind": "attribute", "displayName": "Pretty 
Print", "group": "common", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "To enable pretty printing output nicely 
formatted. Is by default false." },
+    "unmarshalType": { "index": 1, "kind": "attribute", "displayName": 
"Unmarshal Type", "group": "common", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Class name of the java type to use when 
unmarshalling." },
+    "contentTypeHeader": { "index": 2, "kind": "attribute", "displayName": 
"Content Type Header", "group": "common", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether the data format 
should set the Content-Type header with the type from the data format. For 
example application\/xml for data formats marshalling to XML, or 
application\/json for data formats marshalli [...]
   }
 }
diff --git 
a/components/camel-fastjson/src/main/java/org/apache/camel/component/fastjson/FastjsonDataFormat.java
 
b/components/camel-fastjson/src/main/java/org/apache/camel/component/fastjson/FastjsonDataFormat.java
index a21a9cb4c1b7..28d13d35793b 100644
--- 
a/components/camel-fastjson/src/main/java/org/apache/camel/component/fastjson/FastjsonDataFormat.java
+++ 
b/components/camel-fastjson/src/main/java/org/apache/camel/component/fastjson/FastjsonDataFormat.java
@@ -39,7 +39,7 @@ import org.apache.camel.support.service.ServiceSupport;
  * Marshal POJOs to JSON and back using <a 
href="https://github.com/alibaba/fastjson";>Fastjson</a>
  */
 @Dataformat("fastjson")
-@Metadata(includeProperties = 
"unmarshalType,unmarshalTypeName,prettyprint,contentTypeHeader")
+@Metadata(includeProperties = 
"unmarshalType,unmarshalTypeName,prettyPrint,contentTypeHeader")
 public class FastjsonDataFormat extends ServiceSupport
         implements DataFormat, DataFormatName, DataFormatContentTypeHeader, 
CamelContextAware {
 
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifier.java
index 83f0339814b5..14dd6e68a85a 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifier.java
@@ -31,8 +31,10 @@ public class JsonDataFormatReifier extends 
DataFormatReifier<JsonDataFormat> {
 
     @Override
     protected void prepareDataFormatConfig(Map<String, Object> properties) {
-        properties.put("objectMapper", asRef(definition.getObjectMapper()));
+        properties.put("unmarshalType", or(definition.getUnmarshalType(), 
definition.getUnmarshalTypeName()));
+        properties.put("prettyPrint", definition.getPrettyPrint());
         if (definition.getLibrary() == JsonLibrary.Jackson) {
+            properties.put("objectMapper", 
asRef(definition.getObjectMapper()));
             if (definition.getUseDefaultObjectMapper() == null) {
                 // default true
                 properties.put("useDefaultObjectMapper", "true");
@@ -41,27 +43,26 @@ public class JsonDataFormatReifier extends 
DataFormatReifier<JsonDataFormat> {
             }
             properties.put("autoDiscoverObjectMapper", 
definition.getAutoDiscoverObjectMapper());
             properties.put("jsonView", or(definition.getJsonView(), 
definition.getJsonViewTypeName()));
-        } else {
-            properties.put("jsonView", definition.getJsonView());
-        }
-        properties.put("unmarshalType", or(definition.getUnmarshalType(), 
definition.getUnmarshalTypeName()));
-        properties.put("prettyPrint", definition.getPrettyPrint());
-        properties.put("include", definition.getInclude());
-        properties.put("allowJmsType", definition.getAllowJmsType());
-        properties.put("collectionType", or(definition.getCollectionType(), 
definition.getCollectionTypeName()));
-        properties.put("useList", definition.getUseList());
-        properties.put("combineUnicodeSurrogates", 
definition.getCombineUnicodeSurrogates());
-        properties.put("moduleClassNames", definition.getModuleClassNames());
-        properties.put("moduleRefs", definition.getModuleRefs());
-        properties.put("enableFeatures", definition.getEnableFeatures());
-        properties.put("disableFeatures", definition.getDisableFeatures());
-        properties.put("allowUnmarshallType", 
definition.getAllowUnmarshallType());
-        if (definition.getLibrary() == JsonLibrary.Jackson) {
+            properties.put("include", definition.getInclude());
+            properties.put("allowJmsType", definition.getAllowJmsType());
+            properties.put("collectionType", 
or(definition.getCollectionType(), definition.getCollectionTypeName()));
+            properties.put("useList", definition.getUseList());
+            properties.put("combineUnicodeSurrogates", 
definition.getCombineUnicodeSurrogates());
+            properties.put("moduleClassNames", 
definition.getModuleClassNames());
+            properties.put("moduleRefs", definition.getModuleRefs());
+            properties.put("enableFeatures", definition.getEnableFeatures());
+            properties.put("disableFeatures", definition.getDisableFeatures());
+            properties.put("allowUnmarshallType", 
definition.getAllowUnmarshallType());
             properties.put("schemaResolver", 
asRef(definition.getSchemaResolver()));
             properties.put("autoDiscoverSchemaResolver", 
definition.getAutoDiscoverSchemaResolver());
             properties.put("namingStrategy", definition.getNamingStrategy());
             properties.put("timezone", definition.getTimezone());
             properties.put("maxStringLength", definition.getMaxStringLength());
+        } else {
+            properties.put("jsonView", definition.getJsonView());
+        }
+        if (definition.getLibrary() == JsonLibrary.Jsonb) {
+            properties.put("objectMapper", 
asRef(definition.getObjectMapper()));
         }
         if (definition.getLibrary() == JsonLibrary.Fastjson || 
definition.getLibrary() == JsonLibrary.Gson) {
             properties.put("dateFormatPattern", 
definition.getDateFormatPattern());
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifierTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifierTest.java
new file mode 100644
index 000000000000..a5f05c5d4786
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/reifier/dataformat/JsonDataFormatReifierTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.reifier.dataformat;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.dataformat.JsonDataFormat;
+import org.apache.camel.model.dataformat.JsonLibrary;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class JsonDataFormatReifierTest {
+
+    private static final Set<String> JACKSON_ONLY_OPTIONS = Set.of(
+            "objectMapper", "useDefaultObjectMapper", 
"autoDiscoverObjectMapper",
+            "include", "allowJmsType", "collectionType", "useList",
+            "combineUnicodeSurrogates", "moduleClassNames", "moduleRefs",
+            "enableFeatures", "disableFeatures", "allowUnmarshallType",
+            "schemaResolver", "autoDiscoverSchemaResolver", "namingStrategy",
+            "timezone", "maxStringLength");
+
+    @Test
+    public void testGsonDoesNotIncludeJacksonOnlyOptions() {
+        assertNoJacksonOptions(JsonLibrary.Gson);
+    }
+
+    @Test
+    public void testFastjsonDoesNotIncludeJacksonOnlyOptions() {
+        assertNoJacksonOptions(JsonLibrary.Fastjson);
+    }
+
+    @Test
+    public void testJsonbDoesNotIncludeJacksonOnlyOptions() {
+        Map<String, Object> properties = getProperties(JsonLibrary.Jsonb);
+        // Jsonb supports objectMapper, so only check the rest
+        Set<String> jsonbExcluded = Set.of(
+                "useDefaultObjectMapper", "autoDiscoverObjectMapper",
+                "include", "allowJmsType", "collectionType", "useList",
+                "combineUnicodeSurrogates", "moduleClassNames", "moduleRefs",
+                "enableFeatures", "disableFeatures", "allowUnmarshallType",
+                "schemaResolver", "autoDiscoverSchemaResolver", 
"namingStrategy",
+                "timezone", "maxStringLength");
+        for (String option : jsonbExcluded) {
+            assertFalse(properties.containsKey(option),
+                    "Jsonb should not include Jackson-only option: " + option);
+        }
+        assertTrue(properties.containsKey("objectMapper"),
+                "Jsonb should include objectMapper");
+    }
+
+    @Test
+    public void testJacksonIncludesAllOptions() {
+        Map<String, Object> properties = getProperties(JsonLibrary.Jackson);
+        for (String option : JACKSON_ONLY_OPTIONS) {
+            assertTrue(properties.containsKey(option),
+                    "Jackson should include option: " + option);
+        }
+    }
+
+    private void assertNoJacksonOptions(JsonLibrary library) {
+        Map<String, Object> properties = getProperties(library);
+        for (String option : JACKSON_ONLY_OPTIONS) {
+            assertFalse(properties.containsKey(option),
+                    library.name() + " should not include Jackson-only option: 
" + option);
+        }
+    }
+
+    private Map<String, Object> getProperties(JsonLibrary library) {
+        DefaultCamelContext context = new DefaultCamelContext();
+        JsonDataFormat definition = new JsonDataFormat();
+        definition.setLibrary(library);
+        JsonDataFormatReifier reifier = new JsonDataFormatReifier(context, 
definition);
+        Map<String, Object> properties = new LinkedHashMap<>();
+        reifier.prepareDataFormatConfig(properties);
+        return properties;
+    }
+}

Reply via email to