You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/10/16 04:50:04 UTC

[camel] branch master updated: [CAMEL-15692] adding jsonb dataformat (#4452)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 74d638c  [CAMEL-15692] adding jsonb dataformat (#4452)
74d638c is described below

commit 74d638c3e70e330d905139450ba97f9deb0cd5fa
Author: Romain Manni-Bucau <rm...@gmail.com>
AuthorDate: Fri Oct 16 06:49:41 2020 +0200

    [CAMEL-15692] adding jsonb dataformat (#4452)
    
    * [CAMEL-15692] adding jsonb dataformat
    
    * checkstyle fix
    
    * fixing camel-jsonb dataformat doc generation - same workaround than johnzon dataformat
    
    * build update for jsonb
---
 bom/camel-bom/pom.xml                              |   5 +
 camel-dependencies/pom.xml                         |   1 +
 .../camel/catalog/dataformats/json-jsonb.json      |  23 +++
 .../camel/catalog/docs/json-jsonb-dataformat.adoc  |  59 ++++++
 components/camel-jsonb/pom.xml                     |  70 +++++++
 .../component/jsonb/JsonbDataFormatConfigurer.java |  32 ++++
 .../apache/camel/configurer/json-jsonb-dataformat  |   2 +
 .../org/apache/camel/dataformat.properties         |   7 +
 .../org/apache/camel/dataformat/json-jsonb         |   2 +
 .../apache/camel/component/jsonb/json-jsonb.json   |  23 +++
 .../src/main/docs/json-jsonb-dataformat.adoc       |  59 ++++++
 .../camel/component/jsonb/JsonbDataFormat.java     | 212 +++++++++++++++++++++
 .../component/jsonb/JsonbAttributeOrderTest.java   |  74 +++++++
 .../camel/component/jsonb/JsonbDataFormatTest.java |  86 +++++++++
 .../component/jsonb/JsonbJsonDataFormatTest.java   |  31 +--
 .../camel/component/jsonb/JsonbMarshalTest.java    |  88 +++++++++
 .../camel/component/jsonb/JsonbSkipNullTest.java   |  55 ++++++
 .../apache/camel/component/jsonb/NumberPojo.java   | 134 +++++++++++++
 .../jsonb/SpringJsonbJsonDataFormatTest.java       |  75 ++++++++
 .../camel/component/jsonb/TestOtherPojo.java       |  33 ++--
 .../org/apache/camel/component/jsonb/TestPojo.java |  38 ++--
 .../src/test/resources/log4j2.properties           |  28 +++
 .../jsonb/SpringJsonbJsonDataFormatTest.xml        |  63 ++++++
 components/pom.xml                                 |   1 +
 core/camel-allcomponents/pom.xml                   |   4 +
 .../org/apache/camel/model/dataformat/json.json    |   2 +-
 .../apache/camel/model/dataformat/JsonLibrary.java |   3 +-
 .../dataformats/pages/json-jsonb-dataformat.adoc   |  61 ++++++
 parent/pom.xml                                     |   6 +
 .../maven/packaging/PackageDataFormatMojo.java     |  13 +-
 30 files changed, 1245 insertions(+), 45 deletions(-)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index 68af4c7..b0bee86 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -1099,6 +1099,11 @@
       </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
+        <artifactId>camel-jsonb</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
         <artifactId>camel-jsonpath</artifactId>
         <version>${project.version}</version>
       </dependency>
diff --git a/camel-dependencies/pom.xml b/camel-dependencies/pom.xml
index d5a1822..2738c08 100644
--- a/camel-dependencies/pom.xml
+++ b/camel-dependencies/pom.xml
@@ -218,6 +218,7 @@
     <geronimo-jms2-spec-version>1.0-alpha-2</geronimo-jms2-spec-version>
     <geronimo-jpa-spec-version>1.0-alpha-1</geronimo-jpa-spec-version>
     <geronimo-json-spec-version>1.1</geronimo-json-spec-version>
+    <geronimo-jsonb-spec-version>1.0</geronimo-jsonb-spec-version>
     <geronimo-jta-spec-version>1.1.1</geronimo-jta-spec-version>
     <geronimo-ws-metadata-spec-version>1.1.3</geronimo-ws-metadata-spec-version>
     <glassfish-javax-json>1.0.4</glassfish-javax-json>
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/json-jsonb.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/json-jsonb.json
new file mode 100644
index 0000000..f122d2b
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dataformats/json-jsonb.json
@@ -0,0 +1,23 @@
+{
+  "dataformat": {
+    "kind": "dataformat",
+    "name": "json-jsonb",
+    "title": "JSON JSON-B",
+    "description": "Marshal POJOs to JSON and back using JSON-B.",
+    "deprecated": false,
+    "firstVersion": "3.6.0",
+    "label": "dataformat,transformation,json",
+    "javaType": "org.apache.camel.component.jsonb.JsonbDataFormat",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-jsonb",
+    "version": "3.6.0-SNAPSHOT",
+    "modelName": "json",
+    "modelJavaType": "org.apache.camel.model.dataformat.JsonDataFormat"
+  },
+  "properties": {
+    "objectMapper": { "kind": "attribute", "displayName": "Jsonb instance", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Lookup and use the existing Jsonb instance with the given id." },
+    "prettyPrint": { "kind": "attribute", "displayName": "Pretty Print", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "To enable pretty printing output nicely formatted. Is by default false." },
+    "unmarshalTypeName": { "kind": "attribute", "displayName": "Unmarshal Type Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Class name of the java type to use when unmarshalling" }
+  }
+}
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/json-jsonb-dataformat.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/json-jsonb-dataformat.adoc
new file mode 100644
index 0000000..e87423e
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/json-jsonb-dataformat.adoc
@@ -0,0 +1,59 @@
+[[json-jsonb-dataformat]]
+= JSON JSON-B DataFormat
+:docTitle: JSON JSON-B
+:artifactId: camel-jsonb
+:description: Marshal POJOs to JSON and back using JSON-B.
+:since: 3.6
+:supportLevel: Preview
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/dataformats/json-jsonb.adoc[]
+
+*Since Camel {since}*
+
+JSON-B is a Data Format which uses the standard (javax) JSON-B library.
+
+[source,java]
+-------------------------------
+from("activemq:My.Queue").
+  marshal().json(JsonLibrary.Jsonb).
+  to("mqseries:Another.Queue");
+-------------------------------
+
+== JSON-B Options
+
+
+
+// dataformat options: START
+The JSON JSON-B dataformat supports 3 options, which are listed below.
+
+
+
+[width="100%",cols="2s,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| objectMapper |  | String | Lookup and use the existing Jsonb instance with the given id.
+| prettyPrint | false | Boolean | To enable pretty printing output nicely formatted. Is by default false.
+| unmarshalTypeName |  | String | Class name of the java type to use when unmarshalling
+|===
+// dataformat options: END
+
+
+== Dependencies
+
+To use JSON-B in your camel routes you need to add the dependency
+on *camel-jsonb* which implements this data format.
+
+If you use maven you could just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+----------------------------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-jsonb</artifactId>
+  <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
+</dependency>
+----------------------------------------------------------
+
+include::camel-spring-boot::page$jsonb-starter.adoc[]
diff --git a/components/camel-jsonb/pom.xml b/components/camel-jsonb/pom.xml
new file mode 100644
index 0000000..9645c87
--- /dev/null
+++ b/components/camel-jsonb/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>components</artifactId>
+        <version>3.6.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-jsonb</artifactId>
+    <packaging>jar</packaging>
+    <name>Camel :: JSON-B</name>
+    <description>Camel JSON-B support</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-json_1.1_spec</artifactId>
+            <version>${geronimo-json-spec-version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jsonb_1.0_spec</artifactId>
+            <version>${geronimo-jsonb-spec-version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <!-- testing -->
+        <dependency>
+            <groupId>org.apache.johnzon</groupId>
+            <artifactId>johnzon-jsonb</artifactId>
+            <version>${johnzon-version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-spring-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/components/camel-jsonb/src/generated/java/org/apache/camel/component/jsonb/JsonbDataFormatConfigurer.java b/components/camel-jsonb/src/generated/java/org/apache/camel/component/jsonb/JsonbDataFormatConfigurer.java
new file mode 100644
index 0000000..dfa0408
--- /dev/null
+++ b/components/camel-jsonb/src/generated/java/org/apache/camel/component/jsonb/JsonbDataFormatConfigurer.java
@@ -0,0 +1,32 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.jsonb;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class JsonbDataFormatConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) {
+        JsonbDataFormat dataformat = (JsonbDataFormat) target;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "objectmapper":
+        case "objectMapper": dataformat.setObjectMapper(property(camelContext, javax.json.bind.Jsonb.class, value)); return true;
+        case "unmarshaltypename":
+        case "unmarshalTypeName": dataformat.setUnmarshalTypeName(property(camelContext, java.lang.String.class, value)); return true;
+        case "prettyprint":
+        case "prettyPrint": dataformat.setPrettyPrint(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+}
+
diff --git a/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/configurer/json-jsonb-dataformat b/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/configurer/json-jsonb-dataformat
new file mode 100644
index 0000000..fe03fc6
--- /dev/null
+++ b/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/configurer/json-jsonb-dataformat
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.jsonb.JsonbDataFormatConfigurer
diff --git a/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties b/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties
new file mode 100644
index 0000000..0eecbba
--- /dev/null
+++ b/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/dataformat.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+dataFormats=json-jsonb
+groupId=org.apache.camel
+artifactId=camel-jsonb
+version=3.6.0-SNAPSHOT
+projectName=Camel :: JSON-B
+projectDescription=Camel JSON-B support
diff --git a/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/dataformat/json-jsonb b/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/dataformat/json-jsonb
new file mode 100644
index 0000000..a0ee26d
--- /dev/null
+++ b/components/camel-jsonb/src/generated/resources/META-INF/services/org/apache/camel/dataformat/json-jsonb
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.jsonb.JsonbDataFormat
diff --git a/components/camel-jsonb/src/generated/resources/org/apache/camel/component/jsonb/json-jsonb.json b/components/camel-jsonb/src/generated/resources/org/apache/camel/component/jsonb/json-jsonb.json
new file mode 100644
index 0000000..f122d2b
--- /dev/null
+++ b/components/camel-jsonb/src/generated/resources/org/apache/camel/component/jsonb/json-jsonb.json
@@ -0,0 +1,23 @@
+{
+  "dataformat": {
+    "kind": "dataformat",
+    "name": "json-jsonb",
+    "title": "JSON JSON-B",
+    "description": "Marshal POJOs to JSON and back using JSON-B.",
+    "deprecated": false,
+    "firstVersion": "3.6.0",
+    "label": "dataformat,transformation,json",
+    "javaType": "org.apache.camel.component.jsonb.JsonbDataFormat",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-jsonb",
+    "version": "3.6.0-SNAPSHOT",
+    "modelName": "json",
+    "modelJavaType": "org.apache.camel.model.dataformat.JsonDataFormat"
+  },
+  "properties": {
+    "objectMapper": { "kind": "attribute", "displayName": "Jsonb instance", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Lookup and use the existing Jsonb instance with the given id." },
+    "prettyPrint": { "kind": "attribute", "displayName": "Pretty Print", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "To enable pretty printing output nicely formatted. Is by default false." },
+    "unmarshalTypeName": { "kind": "attribute", "displayName": "Unmarshal Type Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Class name of the java type to use when unmarshalling" }
+  }
+}
diff --git a/components/camel-jsonb/src/main/docs/json-jsonb-dataformat.adoc b/components/camel-jsonb/src/main/docs/json-jsonb-dataformat.adoc
new file mode 100644
index 0000000..e87423e
--- /dev/null
+++ b/components/camel-jsonb/src/main/docs/json-jsonb-dataformat.adoc
@@ -0,0 +1,59 @@
+[[json-jsonb-dataformat]]
+= JSON JSON-B DataFormat
+:docTitle: JSON JSON-B
+:artifactId: camel-jsonb
+:description: Marshal POJOs to JSON and back using JSON-B.
+:since: 3.6
+:supportLevel: Preview
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/dataformats/json-jsonb.adoc[]
+
+*Since Camel {since}*
+
+JSON-B is a Data Format which uses the standard (javax) JSON-B library.
+
+[source,java]
+-------------------------------
+from("activemq:My.Queue").
+  marshal().json(JsonLibrary.Jsonb).
+  to("mqseries:Another.Queue");
+-------------------------------
+
+== JSON-B Options
+
+
+
+// dataformat options: START
+The JSON JSON-B dataformat supports 3 options, which are listed below.
+
+
+
+[width="100%",cols="2s,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| objectMapper |  | String | Lookup and use the existing Jsonb instance with the given id.
+| prettyPrint | false | Boolean | To enable pretty printing output nicely formatted. Is by default false.
+| unmarshalTypeName |  | String | Class name of the java type to use when unmarshalling
+|===
+// dataformat options: END
+
+
+== Dependencies
+
+To use JSON-B in your camel routes you need to add the dependency
+on *camel-jsonb* which implements this data format.
+
+If you use maven you could just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+----------------------------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-jsonb</artifactId>
+  <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
+</dependency>
+----------------------------------------------------------
+
+include::camel-spring-boot::page$jsonb-starter.adoc[]
diff --git a/components/camel-jsonb/src/main/java/org/apache/camel/component/jsonb/JsonbDataFormat.java b/components/camel-jsonb/src/main/java/org/apache/camel/component/jsonb/JsonbDataFormat.java
new file mode 100644
index 0000000..ea88a49
--- /dev/null
+++ b/components/camel-jsonb/src/main/java/org/apache/camel/component/jsonb/JsonbDataFormat.java
@@ -0,0 +1,212 @@
+/*
+ * 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.component.jsonb;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Type;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.json.bind.JsonbConfig;
+import javax.json.bind.config.BinaryDataStrategy;
+import javax.json.bind.config.PropertyNamingStrategy;
+import javax.json.bind.config.PropertyOrderStrategy;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataFormatName;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.annotations.Dataformat;
+import org.apache.camel.support.service.ServiceSupport;
+
+/**
+ * Marshal POJOs to JSON and back using JSON-B.
+ */
+@Dataformat("json-jsonb")
+@Metadata(includeProperties = "unmarshalTypeName,objectMapper,prettyPrint,binaryStrategy,encoding,propertyOrder,propertyamingStrategy,skipNull")
+public class JsonbDataFormat extends ServiceSupport implements DataFormat, DataFormatName, CamelContextAware {
+    private CamelContext camelContext;
+    private Jsonb objectMapper;
+    private String unmarshalTypeName;
+    private Type unmarshalType;
+    private boolean prettyPrint;
+    private String encoding = "UTF-8";
+    private String binaryStrategy = BinaryDataStrategy.BASE_64;
+    private String propertyOrder = PropertyOrderStrategy.ANY;
+    private String propertyamingStrategy = PropertyNamingStrategy.IDENTITY;
+    private boolean skipNull = true;
+
+    public JsonbDataFormat() {
+        this(Object.class);
+    }
+
+    /**
+     * Use the default JSON-B {@link Jsonb} and with a custom unmarshal type
+     *
+     * @param unmarshalType the custom unmarshal type
+     */
+    public JsonbDataFormat(Type unmarshalType) {
+        this(null, unmarshalType);
+    }
+
+    /**
+     * Use a custom JSON-B instance and unmarshal type
+     *
+     * @param mapper        the custom mapper
+     * @param unmarshalType the custom unmarshal type
+     */
+    public JsonbDataFormat(Jsonb mapper, Type unmarshalType) {
+        this.objectMapper = mapper;
+        this.unmarshalType = unmarshalType;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public String getDataFormatName() {
+        return "json-jsonb";
+    }
+
+    public Jsonb getObjectMapper() {
+        return objectMapper;
+    }
+
+    /**
+     * Set a custom Jsonb instance, potentially initialized with a custom JsonbConfig.
+     * 
+     * @param objectMapper the Jsonb instance to set.
+     */
+    public void setObjectMapper(Jsonb objectMapper) {
+        this.objectMapper = objectMapper;
+    }
+
+    public Type getUnmarshalType() {
+        return unmarshalType;
+    }
+
+    public void setUnmarshalType(Type unmarshalType) {
+        this.unmarshalType = unmarshalType;
+    }
+
+    public String getUnmarshalTypeName() {
+        return unmarshalTypeName;
+    }
+
+    public void setUnmarshalTypeName(String unmarshalTypeName) {
+        this.unmarshalTypeName = unmarshalTypeName;
+    }
+
+    public boolean isPrettyPrint() {
+        return prettyPrint;
+    }
+
+    public void setPrettyPrint(boolean prettyPrint) {
+        this.prettyPrint = prettyPrint;
+    }
+
+    public String getEncoding() {
+        return encoding;
+    }
+
+    public void setEncoding(String encoding) {
+        this.encoding = encoding;
+    }
+
+    public boolean isSkipNull() {
+        return skipNull;
+    }
+
+    public void setSkipNull(boolean skipNull) {
+        this.skipNull = skipNull;
+    }
+
+    public String getBinaryStrategy() {
+        return binaryStrategy;
+    }
+
+    public void setBinaryStrategy(String binaryStrategy) {
+        this.binaryStrategy = binaryStrategy;
+    }
+
+    public String getPropertyOrder() {
+        return propertyOrder;
+    }
+
+    public void setPropertyOrder(String propertyOrder) {
+        this.propertyOrder = propertyOrder;
+    }
+
+    public String getPropertyamingStrategy() {
+        return propertyamingStrategy;
+    }
+
+    public void setPropertyamingStrategy(String propertyamingStrategy) {
+        this.propertyamingStrategy = propertyamingStrategy;
+    }
+
+    @Override
+    public void marshal(Exchange exchange, Object graph, OutputStream stream) {
+        objectMapper.toJson(graph, stream);
+    }
+
+    @Override
+    public Object unmarshal(Exchange exchange, InputStream stream) throws Exception {
+        // is there a header with the unmarshal type?
+        Type expectedType = unmarshalType;
+        String type = exchange.getIn().getHeader("CamelJsonbUnmarshallType", String.class);
+        if (type != null) {
+            expectedType = exchange.getContext().getClassResolver().resolveMandatoryClass(type);
+        }
+        return objectMapper.fromJson(stream, expectedType);
+    }
+
+    @Override
+    protected void doInit() {
+        if (unmarshalTypeName != null && (unmarshalType == null || unmarshalType == Object.class)) {
+            unmarshalType = camelContext.getClassResolver().resolveClass(unmarshalTypeName);
+        }
+    }
+
+    @Override
+    protected void doStart() {
+        if (objectMapper == null) {
+            objectMapper = JsonbBuilder.create(new JsonbConfig()
+                    .withFormatting(prettyPrint)
+                    .withNullValues(!skipNull)
+                    .withBinaryDataStrategy(binaryStrategy)
+                    .withPropertyOrderStrategy(propertyOrder)
+                    .withPropertyNamingStrategy(propertyamingStrategy)
+                    .withEncoding(encoding));
+        }
+    }
+
+    @Override
+    protected void doStop() {
+        // noop
+    }
+}
diff --git a/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbAttributeOrderTest.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbAttributeOrderTest.java
new file mode 100644
index 0000000..9c87522
--- /dev/null
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbAttributeOrderTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.component.jsonb;
+
+import java.math.BigDecimal;
+
+import javax.json.bind.config.PropertyOrderStrategy;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class JsonbAttributeOrderTest extends CamelTestSupport {
+
+    final String expectedJson
+            = "{\"bg\":123.123,\"bool\":true,\"doubleNumber\":123.123,\"floatNumber\":123.0,\"intNumber\":123,\"longNumber\":123}";
+
+    @Test
+    public void testMarshalAndUnmarshalMap() throws Exception {
+        NumberPojo nc = new NumberPojo();
+        nc.setBg(new BigDecimal("123.123"));
+        nc.setDoubleNumber(123.123);
+        nc.setBool(true);
+        nc.setFloatNumber(123);
+        nc.setLongNumber(123L);
+        nc.setIntNumber(123);
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(NumberPojo.class);
+        mock.message(0).body().isEqualTo(nc);
+
+        Object marshalled = template.requestBody("direct:in", nc);
+        String marshalledAsString = context.getTypeConverter().convertTo(String.class, marshalled);
+        assertEquals(expectedJson, marshalledAsString);
+
+        template.sendBody("direct:back", marshalled);
+
+        mock.assertIsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+
+            @Override
+            public void configure() {
+                JsonbDataFormat format = new JsonbDataFormat(NumberPojo.class);
+                format.setPropertyOrder(PropertyOrderStrategy.LEXICOGRAPHICAL);
+
+                from("direct:in").marshal(format);
+                from("direct:back").unmarshal(format).to("mock:reverse");
+            }
+        };
+    }
+
+}
diff --git a/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbDataFormatTest.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbDataFormatTest.java
new file mode 100644
index 0000000..0c57641
--- /dev/null
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbDataFormatTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.component.jsonb;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.johnzon.mapper.reflection.JohnzonParameterizedType;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class JsonbDataFormatTest {
+
+    @Test
+    public void testString() throws Exception {
+        testJson("\"A string\"", "A string", String.class, null);
+    }
+
+    @Test
+    public void testMap() throws Exception {
+        testJson("{\"value\":123}", Collections.singletonMap("value", 123), Map.class, null);
+    }
+
+    @Test
+    public void testList() throws Exception {
+        JohnzonParameterizedType type = new JohnzonParameterizedType(List.class, Map.class);
+        testJson("[{\"value\":123}]",
+                new ArrayList<>(Collections.singletonList(Collections.singletonMap("value", 123))), null, type);
+    }
+
+    @Test
+    public void testArray() throws Exception {
+        testJson("{\"value\":123}", new ArrayList<String>(), ArrayList.class, null);
+    }
+
+    @Test
+    public void testSkipEmptyArray() throws Exception {
+        JohnzonParameterizedType type = new JohnzonParameterizedType(ArrayList.class, ArrayList.class);
+        testJson("[{\"value\":123}]",
+                new ArrayList<>(Collections.singletonList(Collections.emptyList())), null, type);
+    }
+
+    private void testJson(String json, Object expected, Class<?> unmarshalType, JohnzonParameterizedType parameterizedType)
+            throws Exception {
+        Object unmarshalled;
+        JsonbDataFormat jsonbDataFormat = null;
+
+        try {
+            if (unmarshalType != null) {
+                jsonbDataFormat = new JsonbDataFormat(unmarshalType);
+            } else {
+                jsonbDataFormat = new JsonbDataFormat(parameterizedType);
+            }
+            jsonbDataFormat.doStart();
+            try (InputStream in = new ByteArrayInputStream(json.getBytes())) {
+                unmarshalled = jsonbDataFormat.unmarshal(new DefaultExchange(new DefaultCamelContext()), in);
+            }
+            assertEquals(expected, unmarshalled);
+        } finally {
+            if (jsonbDataFormat != null) {
+                jsonbDataFormat.close();
+            }
+        }
+    }
+}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbJsonDataFormatTest.java
similarity index 51%
copy from core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
copy to components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbJsonDataFormatTest.java
index 99722d4..30b89cb 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbJsonDataFormatTest.java
@@ -14,22 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.model.dataformat;
+package org.apache.camel.component.jsonb;
 
-import javax.xml.bind.annotation.XmlEnum;
-import javax.xml.bind.annotation.XmlType;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.dataformat.JsonLibrary;
 
-/**
- * Supported JSON marshalers.
- */
-@XmlType
-@XmlEnum
-public enum JsonLibrary {
+public class JsonbJsonDataFormatTest extends JsonbMarshalTest {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:in").marshal().json(JsonLibrary.Jsonb);
+                from("direct:back").unmarshal().json(JsonLibrary.Jsonb).to("mock:reverse");
 
-    XStream,
-    Jackson,
-    Johnzon,
-    Gson,
-    Fastjson
+                from("direct:inPojo").marshal().json(JsonLibrary.Jsonb);
+                from("direct:backPojo").unmarshal().json(JsonLibrary.Jsonb, TestPojo.class).to("mock:reversePojo");
+            }
+        };
+    }
 
 }
diff --git a/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbMarshalTest.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbMarshalTest.java
new file mode 100644
index 0000000..92cabae
--- /dev/null
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbMarshalTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.component.jsonb;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class JsonbMarshalTest extends CamelTestSupport {
+
+    @Test
+    public void testMarshalAndUnmarshalMap() throws Exception {
+        Map<String, Object> in = new HashMap<>();
+        in.put("name", "Camel");
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Map.class);
+        mock.message(0).body().isEqualTo(in);
+
+        Object marshalled = template.requestBody("direct:in", in);
+        String marshalledAsString = context.getTypeConverter().convertTo(String.class, marshalled);
+        assertEquals("{\"name\":\"Camel\"}", marshalledAsString);
+
+        template.sendBody("direct:back", marshalled);
+
+        mock.assertIsSatisfied();
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalPojo() throws Exception {
+        TestPojo in = new TestPojo();
+        in.setName("Camel");
+
+        MockEndpoint mock = getMockEndpoint("mock:reversePojo");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(TestPojo.class);
+        mock.message(0).body().isEqualTo(in);
+
+        Object marshalled = template.requestBody("direct:inPojo", in);
+        String marshalledAsString = context.getTypeConverter().convertTo(String.class, marshalled);
+        assertEquals("{\"name\":\"Camel\"}", marshalledAsString);
+
+        template.sendBody("direct:backPojo", marshalled);
+
+        mock.assertIsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+
+            @Override
+            public void configure() {
+                JsonbDataFormat format = new JsonbDataFormat();
+
+                from("direct:in").marshal(format);
+                from("direct:back").unmarshal(format).to("mock:reverse");
+
+                JsonbDataFormat formatPojo = new JsonbDataFormat(TestPojo.class);
+
+                from("direct:inPojo").marshal(formatPojo);
+                from("direct:backPojo").unmarshal(formatPojo).to("mock:reversePojo");
+            }
+        };
+    }
+
+}
diff --git a/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbSkipNullTest.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbSkipNullTest.java
new file mode 100644
index 0000000..14f3298
--- /dev/null
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/JsonbSkipNullTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.component.jsonb;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+public class JsonbSkipNullTest extends CamelTestSupport {
+
+    @Test
+    public void testMmarshalPojo() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:marshal");
+        mock.expectedMessageCount(1);
+        mock.message(0).body(String.class).isEqualTo("{\"name\":\"Camel\"}");
+
+        TestOtherPojo pojo = new TestOtherPojo();
+        pojo.setName("Camel");
+        pojo.setCountry(null);
+
+        template.sendBody("direct:marshal", pojo);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+
+            @Override
+            public void configure() {
+                JsonbDataFormat format = new JsonbDataFormat();
+                format.setSkipNull(true);
+
+                from("direct:marshal").marshal(format).to("mock:marshal");
+            }
+        };
+    }
+
+}
diff --git a/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/NumberPojo.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/NumberPojo.java
new file mode 100644
index 0000000..458f51c
--- /dev/null
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/NumberPojo.java
@@ -0,0 +1,134 @@
+/*
+ * 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.component.jsonb;
+
+import java.math.BigDecimal;
+
+public class NumberPojo {
+    private BigDecimal bg;
+    private int intNumber;
+    private long longNumber;
+    private double doubleNumber;
+    private float floatNumber;
+    private boolean bool;
+
+    public BigDecimal getBg() {
+        return bg;
+    }
+
+    public void setBg(final BigDecimal bg) {
+        this.bg = bg;
+    }
+
+    public int getIntNumber() {
+        return intNumber;
+    }
+
+    public void setIntNumber(final int intNumber) {
+        this.intNumber = intNumber;
+    }
+
+    public long getLongNumber() {
+        return longNumber;
+    }
+
+    public void setLongNumber(final long longNumber) {
+        this.longNumber = longNumber;
+    }
+
+    public double getDoubleNumber() {
+        return doubleNumber;
+    }
+
+    public void setDoubleNumber(final double doubleNumber) {
+        this.doubleNumber = doubleNumber;
+    }
+
+    public float getFloatNumber() {
+        return floatNumber;
+    }
+
+    public void setFloatNumber(final float floatNumber) {
+        this.floatNumber = floatNumber;
+    }
+
+    public boolean isBool() {
+        return bool;
+    }
+
+    public void setBool(final boolean bool) {
+        this.bool = bool;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((bg == null) ? 0 : bg.hashCode());
+        result = prime * result + (bool ? 1231 : 1237);
+        long temp;
+        temp = Double.doubleToLongBits(doubleNumber);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        result = prime * result + Float.floatToIntBits(floatNumber);
+        result = prime * result + intNumber;
+        result = prime * result + (int) (longNumber ^ (longNumber >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final NumberPojo other = (NumberPojo) obj;
+        if (bg == null) {
+            if (other.bg != null) {
+                return false;
+            }
+        } else if (!bg.equals(other.bg)) {
+            return false;
+        }
+        if (bool != other.bool) {
+            return false;
+        }
+        if (Double.doubleToLongBits(doubleNumber) != Double.doubleToLongBits(other.doubleNumber)) {
+            return false;
+        }
+        if (Float.floatToIntBits(floatNumber) != Float.floatToIntBits(other.floatNumber)) {
+            return false;
+        }
+        if (intNumber != other.intNumber) {
+            return false;
+        }
+        if (longNumber != other.longNumber) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "NumberPojo [bg=" + bg + ", intNumber=" + intNumber + ", longNumber=" + longNumber + ", doubleNumber="
+               + doubleNumber + ", floatNumber=" + floatNumber + ", bool=" + bool + "]";
+    }
+}
diff --git a/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/SpringJsonbJsonDataFormatTest.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/SpringJsonbJsonDataFormatTest.java
new file mode 100644
index 0000000..54fcc1e
--- /dev/null
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/SpringJsonbJsonDataFormatTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.component.jsonb;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.spring.junit5.CamelSpringTestSupport;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class SpringJsonbJsonDataFormatTest extends CamelSpringTestSupport {
+
+    @Test
+    public void testMarshalAndUnmarshalMap() throws Exception {
+        Map<String, Object> in = new HashMap<>();
+        in.put("name", "Camel");
+
+        MockEndpoint mock = getMockEndpoint("mock:reverse");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Map.class);
+        mock.message(0).body().isEqualTo(in);
+
+        Object marshalled = template.requestBody("direct:in", in);
+        String marshalledAsString = context.getTypeConverter().convertTo(String.class, marshalled);
+        assertEquals("{\"name\":\"Camel\"}", marshalledAsString);
+
+        template.sendBody("direct:back", marshalled);
+
+        mock.assertIsSatisfied();
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalPojo() throws Exception {
+        TestPojo in = new TestPojo();
+        in.setName("Camel");
+
+        MockEndpoint mock = getMockEndpoint("mock:reversePojo");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(TestPojo.class);
+        mock.message(0).body().isEqualTo(in);
+
+        Object marshalled = template.requestBody("direct:inPojo", in);
+        String marshalledAsString = context.getTypeConverter().convertTo(String.class, marshalled);
+        assertEquals("{\"name\":\"Camel\"}", marshalledAsString);
+
+        template.sendBody("direct:backPojo", marshalled);
+
+        mock.assertIsSatisfied();
+    }
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/component/jsonb/SpringJsonbJsonDataFormatTest.xml");
+    }
+
+}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/TestOtherPojo.java
similarity index 66%
copy from core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
copy to components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/TestOtherPojo.java
index 99722d4..466692c 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/TestOtherPojo.java
@@ -14,22 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.model.dataformat;
+package org.apache.camel.component.jsonb;
 
-import javax.xml.bind.annotation.XmlEnum;
-import javax.xml.bind.annotation.XmlType;
+public class TestOtherPojo {
 
-/**
- * Supported JSON marshalers.
- */
-@XmlType
-@XmlEnum
-public enum JsonLibrary {
+    private String name;
+    private String country;
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCountry() {
+        return country;
+    }
 
-    XStream,
-    Jackson,
-    Johnzon,
-    Gson,
-    Fastjson
+    public void setCountry(String country) {
+        this.country = country;
+    }
 
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/TestPojo.java
similarity index 60%
copy from core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
copy to components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/TestPojo.java
index 99722d4..465380e 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
+++ b/components/camel-jsonb/src/test/java/org/apache/camel/component/jsonb/TestPojo.java
@@ -14,22 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.model.dataformat;
+package org.apache.camel.component.jsonb;
 
-import javax.xml.bind.annotation.XmlEnum;
-import javax.xml.bind.annotation.XmlType;
+public class TestPojo {
 
-/**
- * Supported JSON marshalers.
- */
-@XmlType
-@XmlEnum
-public enum JsonLibrary {
+    private String name;
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return this.name.equals(((TestPojo) obj).getName());
+    }
 
-    XStream,
-    Jackson,
-    Johnzon,
-    Gson,
-    Fastjson
+    @Override
+    public int hashCode() {
+        return name != null ? name.hashCode() : 0;
+    }
 
+    @Override
+    public String toString() {
+        return "TestPojo[" + name + "]";
+    }
 }
diff --git a/components/camel-jsonb/src/test/resources/log4j2.properties b/components/camel-jsonb/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..f3373d1
--- /dev/null
+++ b/components/camel-jsonb/src/test/resources/log4j2.properties
@@ -0,0 +1,28 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-johnzon-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
diff --git a/components/camel-jsonb/src/test/resources/org/apache/camel/component/jsonb/SpringJsonbJsonDataFormatTest.xml b/components/camel-jsonb/src/test/resources/org/apache/camel/component/jsonb/SpringJsonbJsonDataFormatTest.xml
new file mode 100644
index 0000000..50f1e7f
--- /dev/null
+++ b/components/camel-jsonb/src/test/resources/org/apache/camel/component/jsonb/SpringJsonbJsonDataFormatTest.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+    ">
+
+    <!-- START SNIPPET: e1 -->
+    <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+
+        <!-- we define the json johnzon data formats to be used -->
+        <dataFormats>
+            <!-- this uses the default unmarshal type that is a Map based -->
+            <json id="jsonb" library="Jsonb"/>
+            <!-- and this one uses our own TestPojo class as unmarshal type -->
+            <json id="pojo" library="Jsonb" unmarshalTypeName="org.apache.camel.component.jsonb.TestPojo"/>
+        </dataFormats>
+
+        <route>
+            <from uri="direct:in"/>
+            <marshal><custom ref="jsonb"/></marshal>
+        </route>
+
+        <route>
+            <from uri="direct:back"/>
+            <unmarshal><custom ref="jsonb"/></unmarshal>
+            <to uri="mock:reverse"/>
+        </route>
+
+        <route>
+            <from uri="direct:inPojo"/>
+            <marshal><custom ref="pojo"/></marshal>
+        </route>
+
+        <route>
+            <from uri="direct:backPojo"/>
+            <unmarshal><custom ref="pojo"/></unmarshal>
+            <to uri="mock:reversePojo"/>
+        </route>
+
+    </camelContext>
+    <!-- END SNIPPET: e1 -->
+
+</beans>
diff --git a/components/pom.xml b/components/pom.xml
index f7aa5b2..64f4752 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -257,6 +257,7 @@
         <module>camel-json-validator</module>
         <module>camel-jsonapi</module>
         <module>camel-jsonata</module>
+        <module>camel-jsonb</module>
         <module>camel-jsonpath</module>
         <module>camel-jt400</module>
         <module>camel-jta</module>
diff --git a/core/camel-allcomponents/pom.xml b/core/camel-allcomponents/pom.xml
index bea3f73..12a3ae4 100644
--- a/core/camel-allcomponents/pom.xml
+++ b/core/camel-allcomponents/pom.xml
@@ -748,6 +748,10 @@
 		</dependency>
 		<dependency>
 			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-jsonb</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.camel</groupId>
 			<artifactId>camel-jsonpath</artifactId>
 		</dependency>
 		<dependency>
diff --git a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dataformat/json.json b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dataformat/json.json
index c69c0a7..32584b0 100644
--- a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dataformat/json.json
+++ b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/dataformat/json.json
@@ -14,7 +14,7 @@
     "objectMapper": { "kind": "attribute", "displayName": "Object Mapper", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Lookup and use the existing ObjectMapper with the given id when using Jackson." },
     "useDefaultObjectMapper": { "kind": "attribute", "displayName": "Use Default Object Mapper", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": true, "description": "Whether to lookup and use default Jackson ObjectMapper from the registry." },
     "prettyPrint": { "kind": "attribute", "displayName": "Pretty Print", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "To enable pretty printing output nicely formatted. Is by default false." },
-    "library": { "kind": "attribute", "displayName": "Library", "required": false, "type": "enum", "javaType": "org.apache.camel.model.dataformat.JsonLibrary", "enum": [ "fastjson", "gson", "jackson", "johnzon", "x-stream" ], "deprecated": false, "secret": false, "defaultValue": "Jackson", "description": "Which json library to use." },
+    "library": { "kind": "attribute", "displayName": "Library", "required": false, "type": "enum", "javaType": "org.apache.camel.model.dataformat.JsonLibrary", "enum": [ "fastjson", "gson", "jackson", "johnzon", "jsonb", "x-stream" ], "deprecated": false, "secret": false, "defaultValue": "Jackson", "description": "Which json library to use." },
     "unmarshalTypeName": { "kind": "attribute", "displayName": "Unmarshal Type Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Class name of the java type to use when unmarshalling" },
     "jsonView": { "kind": "attribute", "displayName": "Json View", "required": false, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "secret": false, "description": "When marshalling a POJO to JSON you might want to exclude certain fields from the JSON output. With Jackson you can use JSON views to accomplish this. This option is to refer to the class which has JsonView annotations" },
     "include": { "kind": "attribute", "displayName": "Include", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "If you want to marshal a pojo to JSON, and the pojo has some fields with null values. And you want to skip these null values, you can set this option to NON_NULL" },
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
index 99722d4..18c1ec4 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/JsonLibrary.java
@@ -30,6 +30,7 @@ public enum JsonLibrary {
     Jackson,
     Johnzon,
     Gson,
-    Fastjson
+    Fastjson,
+    Jsonb
 
 }
diff --git a/docs/components/modules/dataformats/pages/json-jsonb-dataformat.adoc b/docs/components/modules/dataformats/pages/json-jsonb-dataformat.adoc
new file mode 100644
index 0000000..39f4889
--- /dev/null
+++ b/docs/components/modules/dataformats/pages/json-jsonb-dataformat.adoc
@@ -0,0 +1,61 @@
+[[json-jsonb-dataformat]]
+= JSON JSON-B DataFormat
+//THIS FILE IS COPIED: EDIT THE SOURCE FILE:
+:page-source: components/camel-jsonb/src/main/docs/json-jsonb-dataformat.adoc
+:docTitle: JSON JSON-B
+:artifactId: camel-jsonb
+:description: Marshal POJOs to JSON and back using JSON-B.
+:since: 3.6
+:supportLevel: Preview
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/dataformats/json-jsonb.adoc[]
+
+*Since Camel {since}*
+
+JSON-B is a Data Format which uses the standard (javax) JSON-B library.
+
+[source,java]
+-------------------------------
+from("activemq:My.Queue").
+  marshal().json(JsonLibrary.Jsonb).
+  to("mqseries:Another.Queue");
+-------------------------------
+
+== JSON-B Options
+
+
+
+// dataformat options: START
+The JSON JSON-B dataformat supports 3 options, which are listed below.
+
+
+
+[width="100%",cols="2s,1m,1m,6",options="header"]
+|===
+| Name | Default | Java Type | Description
+| objectMapper |  | String | Lookup and use the existing Jsonb instance with the given id.
+| prettyPrint | false | Boolean | To enable pretty printing output nicely formatted. Is by default false.
+| unmarshalTypeName |  | String | Class name of the java type to use when unmarshalling
+|===
+// dataformat options: END
+
+
+== Dependencies
+
+To use JSON-B in your camel routes you need to add the dependency
+on *camel-jsonb* which implements this data format.
+
+If you use maven you could just add the following to your pom.xml,
+substituting the version number for the latest & greatest release (see
+the download page for the latest versions).
+
+[source,xml]
+----------------------------------------------------------
+<dependency>
+  <groupId>org.apache.camel</groupId>
+  <artifactId>camel-jsonb</artifactId>
+  <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
+</dependency>
+----------------------------------------------------------
+
+include::camel-spring-boot::page$jsonb-starter.adoc[]
diff --git a/parent/pom.xml b/parent/pom.xml
index b15413d..50c5677 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -202,6 +202,7 @@
         <geronimo-jms2-spec-version>1.0-alpha-2</geronimo-jms2-spec-version>
         <geronimo-jpa-spec-version>1.0-alpha-1</geronimo-jpa-spec-version>
         <geronimo-json-spec-version>1.1</geronimo-json-spec-version>
+        <geronimo-jsonb-spec-version>1.0</geronimo-jsonb-spec-version>
         <geronimo-jta-spec-version>1.1.1</geronimo-jta-spec-version>
         <geronimo-ws-metadata-spec-version>1.1.3</geronimo-ws-metadata-spec-version>
         <gmetric4j-version>1.0.10</gmetric4j-version>
@@ -1722,6 +1723,11 @@
 			</dependency>
 			<dependency>
 				<groupId>org.apache.camel</groupId>
+				<artifactId>camel-jsonb</artifactId>
+				<version>${project.version}</version>
+			</dependency>
+			<dependency>
+				<groupId>org.apache.camel</groupId>
 				<artifactId>camel-jsonpath</artifactId>
 				<version>${project.version}</version>
 			</dependency>
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PackageDataFormatMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PackageDataFormatMojo.java
index aff0d04..5dfdff5 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PackageDataFormatMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PackageDataFormatMojo.java
@@ -359,6 +359,10 @@ public class PackageDataFormatMojo extends AbstractGeneratorMojo {
                 option.setDisplayName("Mapper");
                 option.setDescription("Lookup and use the existing Mapper with the given id.");
             }
+            if ("objectMapper".equals(option.getName()) && "json-jsonb".equals(name)) {
+                option.setDisplayName("Jsonb instance");
+                option.setDescription("Lookup and use the existing Jsonb instance with the given id.");
+            }
             if ("library".equals(option.getName()) && "json".equals(model.getModelName())) {
                 switch (name) {
                     case "json-gson":
@@ -370,6 +374,9 @@ public class PackageDataFormatMojo extends AbstractGeneratorMojo {
                     case "json-johnzon":
                         option.setDefaultValue("Johnzon");
                         break;
+                    case "json-jsonb":
+                        option.setDefaultValue("JSON-B");
+                        break;
                     case "json-fastson":
                         option.setDefaultValue("Fastjson");
                         break;
@@ -419,7 +426,7 @@ public class PackageDataFormatMojo extends AbstractGeneratorMojo {
     private static String asModelName(String name) {
         // special for some data formats
         if ("json-gson".equals(name) || "json-jackson".equals(name) || "json-johnzon".equals(name)
-                || "json-xstream".equals(name) || "json-fastjson".equals(name)) {
+                || "json-xstream".equals(name) || "json-fastjson".equals(name) || "json-jsonb".equals(name)) {
             return "json";
         } else if ("bindy-csv".equals(name) || "bindy-fixed".equals(name) || "bindy-kvp".equals(name)) {
             return "bindy";
@@ -437,6 +444,8 @@ public class PackageDataFormatMojo extends AbstractGeneratorMojo {
                 return "2.0.0";
             case "json-johnzon":
                 return "2.18.0";
+            case "json-jsonb":
+                return "3.6.0";
             case "json-xstream":
                 return "2.0.0";
             case "json-fastjson":
@@ -455,6 +464,8 @@ public class PackageDataFormatMojo extends AbstractGeneratorMojo {
             return "JSON Jackson";
         } else if ("json-johnzon".equals(name)) {
             return "JSON Johnzon";
+        } else if ("json-jsonb".equals(name)) {
+            return "JSON JSON-B";
         } else if ("json-xstream".equals(name)) {
             return "JSON XStream";
         } else if ("json-fastjson".equals(name)) {