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; + } +}
