Merge pull request #91 from dblevins/exception-message-improvements

Exception message improvements
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DeserializationExceptionMessagesTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DeserializationExceptionMessagesTest.java
new file mode 100644
index 0000000..f7a7ff1
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/DeserializationExceptionMessagesTest.java
@@ -0,0 +1,1540 @@
+/*
+ * 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.johnzon.jsonb;
+
+import org.junit.Test;
+
+import javax.json.bind.JsonbException;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class DeserializationExceptionMessagesTest {
+
+
+    @Test
+    public void objectFromString() throws Exception {
+        assertMessage("{ \"object\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'object' of type Color cannot be mapped to json string value: \"Supercalifragilisti.." +
+                        ".\nMissing a Converter for type class org.apache.johnzon.jsonb.DeserializationExceptionMessagesTest$C" +
+                        "olor to convert the JSON String 'Supercalifragilisticexpialidocious' . Please register a custom conv" +
+                        "erter for it.");
+    }
+
+    @Test
+    public void objectFromNumber() throws Exception {
+        assertMessage("{ \"object\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'object' of type Color cannot be mapped to json numeric value: 122333444455555.6666." +
+                        "..\nUnable to parse json numeric value to class org.apache.johnzon.jsonb.DeserializationExceptionMess" +
+                        "agesTest$Color: 122333444455555.6666...");
+    }
+
+    @Test
+    public void objectFromBoolean() throws Exception {
+        assertMessage("{ \"object\" : true }",
+                "Widget property 'object' of type Color cannot be mapped to json boolean value: true\nUnable to parse " +
+                        "json boolean value to class org.apache.johnzon.jsonb.DeserializationExceptionMessagesTest$Color: tru" +
+                        "e");
+    }
+
+    @Test
+    public void objectFromArrayOfObject() throws Exception {
+        assertMessage("{ \"object\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'object' of type Color cannot be mapped to json array value: [{\"red\":255,\"green\":..." +
+                        "\ntype class org.apache.johnzon.jsonb.DeserializationExceptionMessagesTest$Color not supported");
+    }
+
+    @Test
+    public void objectFromArrayOfString() throws Exception {
+        assertMessage("{ \"object\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'object' of type Color cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"..." +
+                        "\ntype class org.apache.johnzon.jsonb.DeserializationExceptionMessagesTest$Color not supported");
+    }
+
+    @Test
+    public void objectFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"object\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'object' of type Color cannot be mapped to json array value: [2,3,5,7,11,13,17,19..." +
+                        "\ntype class org.apache.johnzon.jsonb.DeserializationExceptionMessagesTest$Color not supported");
+    }
+
+    @Test
+    public void objectFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"object\" : [true,false,true,true,false] }",
+                "Widget property 'object' of type Color cannot be mapped to json array value: [true,false,true,tru..." +
+                        "\ntype class org.apache.johnzon.jsonb.DeserializationExceptionMessagesTest$Color not supported");
+    }
+
+    @Test
+    public void stringFromArrayOfObject() throws Exception {
+        assertMessage("{ \"string\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'string' of type String cannot be mapped to json array value: [{\"red\":255,\"green\":.." +
+                        ".\nclass java.lang.String does not support json array value: [{\"red\":255,\"green\":...");
+    }
+
+    @Test
+    public void stringFromArrayOfString() throws Exception {
+        assertMessage("{ \"string\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'string' of type String cannot be mapped to json array value: [\"Klaatu\",\"barada\",\".." +
+                        ".\nclass java.lang.String does not support json array value: [\"Klaatu\",\"barada\",\"...");
+    }
+
+    @Test
+    public void stringFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"string\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'string' of type String cannot be mapped to json array value: [2,3,5,7,11,13,17,19.." +
+                        ".\nclass java.lang.String does not support json array value: [2,3,5,7,11,13,17,19...");
+    }
+
+    @Test
+    public void stringFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"string\" : [true,false,true,true,false] }",
+                "Widget property 'string' of type String cannot be mapped to json array value: [true,false,true,tru.." +
+                        ".\nclass java.lang.String does not support json array value: [true,false,true,tru...");
+    }
+
+    @Test
+    public void numberFromObject() throws Exception {
+        assertMessage("{ \"number\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'number' of type Integer cannot be mapped to json object value: {\"red\":255,\"green\":1" +
+                        "...\nUnable to map json object value to class java.lang.Integer: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void numberFromString() throws Exception {
+        assertMessage("{ \"number\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'number' of type Integer cannot be mapped to json string value: \"Supercalifragilisti" +
+                        "...\nFor input string: \"Supercalifragilisticexpialidocious\"");
+    }
+
+    @Test
+    public void numberFromBoolean() throws Exception {
+        assertMessage("{ \"number\" : true }",
+                "Widget property 'number' of type Integer cannot be mapped to json boolean value: true\nUnable to pars" +
+                        "e json boolean value to class java.lang.Integer: true");
+    }
+
+    @Test
+    public void numberFromArrayOfObject() throws Exception {
+        assertMessage("{ \"number\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'number' of type Integer cannot be mapped to json array value: [{\"red\":255,\"green\":." +
+                        "..\ntype class java.lang.Integer not supported");
+    }
+
+    @Test
+    public void numberFromArrayOfString() throws Exception {
+        assertMessage("{ \"number\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'number' of type Integer cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"." +
+                        "..\ntype class java.lang.Integer not supported");
+    }
+
+    @Test
+    public void numberFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"number\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'number' of type Integer cannot be mapped to json array value: [2,3,5,7,11,13,17,19." +
+                        "..\ntype class java.lang.Integer not supported");
+    }
+
+    @Test
+    public void numberFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"number\" : [true,false,true,true,false] }",
+                "Widget property 'number' of type Integer cannot be mapped to json array value: [true,false,true,tru." +
+                        "..\ntype class java.lang.Integer not supported");
+    }
+
+    @Test
+    public void intPrimitiveFromObject() throws Exception {
+        assertMessage("{ \"intPrimitive\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json object value: {\"red\":255,\"green\"" +
+                        ":1...\nUnable to map json object value to int: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void intPrimitiveFromString() throws Exception {
+        assertMessage("{ \"intPrimitive\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json string value: \"Supercalifragilis" +
+                        "ti...\nMissing a Converter for type int to convert the JSON String 'Supercalifragilisticexpialidociou" +
+                        "s' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void intPrimitiveFromNumber() throws Exception {
+        assertMessage("{ \"intPrimitive\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json numeric value: 122333444455555.6" +
+                        "666...\nNot an int/long, use other value readers");
+    }
+
+    @Test
+    public void intPrimitiveFromBoolean() throws Exception {
+        assertMessage("{ \"intPrimitive\" : true }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json boolean value: true\nUnable to pa" +
+                        "rse json boolean value to int: true");
+    }
+
+    @Test
+    public void intPrimitiveFromNull() throws Exception {
+        assertMessage("{ \"intPrimitive\" : null }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json value: null\nError calling public" +
+                        " void org.apache.johnzon.jsonb.DeserializationExceptionMessagesTest$Widget.setIntPrimitive(int)");
+    }
+
+    @Test
+    public void intPrimitiveFromArrayOfObject() throws Exception {
+        assertMessage("{ \"intPrimitive\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json array value: [{\"red\":255,\"green\"" +
+                        ":...\ntype int not supported");
+    }
+
+    @Test
+    public void intPrimitiveFromArrayOfString() throws Exception {
+        assertMessage("{ \"intPrimitive\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json array value: [\"Klaatu\",\"barada\"," +
+                        "\"...\ntype int not supported");
+    }
+
+    @Test
+    public void intPrimitiveFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"intPrimitive\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json array value: [2,3,5,7,11,13,17,1" +
+                        "9...\ntype int not supported");
+    }
+
+    @Test
+    public void intPrimitiveFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"intPrimitive\" : [true,false,true,true,false] }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json array value: [true,false,true,tr" +
+                        "u...\ntype int not supported");
+    }
+
+    @Test
+    public void booleanFromObject() throws Exception {
+        assertMessage("{ \"bool\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json object value: {\"red\":255,\"green\":1.." +
+                        ".\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void booleanFromString() throws Exception {
+        assertMessage("{ \"bool\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json string value: \"Supercalifragilisti.." +
+                        ".\nUnable to parse json string value to boolean: \"Supercalifragilisti...");
+    }
+
+    @Test
+    public void booleanFromNumber() throws Exception {
+        assertMessage("{ \"bool\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json numeric value: 122333444455555.6666." +
+                        "..\nUnable to parse json numeric value to boolean: 122333444455555.6666...");
+    }
+
+    @Test
+    public void booleanFromArrayOfObject() throws Exception {
+        assertMessage("{ \"bool\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json array value: [{\"red\":255,\"green\":..." +
+                        "\nUnable to parse json array value to boolean: [{\"red\":255,\"green\":...");
+    }
+
+    @Test
+    public void booleanFromArrayOfString() throws Exception {
+        assertMessage("{ \"bool\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"..." +
+                        "\nUnable to parse json array value to boolean: [\"Klaatu\",\"barada\",\"...");
+    }
+
+    @Test
+    public void booleanFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"bool\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json array value: [2,3,5,7,11,13,17,19..." +
+                        "\nUnable to parse json array value to boolean: [2,3,5,7,11,13,17,19...");
+    }
+
+    @Test
+    public void booleanFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"bool\" : [true,false,true,true,false] }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json array value: [true,false,true,tru..." +
+                        "\nUnable to parse json array value to boolean: [true,false,true,tru...");
+    }
+
+    @Test
+    public void boolPrimitiveFromObject() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json object value: {\"red\":255,\"g" +
+                        "reen\":1...\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void boolPrimitiveFromString() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json string value: \"Supercalifra" +
+                        "gilisti...\nUnable to parse json string value to boolean: \"Supercalifragilisti...");
+    }
+
+    @Test
+    public void boolPrimitiveFromNumber() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json numeric value: 122333444455" +
+                        "555.6666...\nUnable to parse json numeric value to boolean: 122333444455555.6666...");
+    }
+
+    @Test
+    public void boolPrimitiveFromNull() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : null }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json value: null\nError calling p" +
+                        "ublic void org.apache.johnzon.jsonb.DeserializationExceptionMessagesTest$Widget.setBoolPrimitive(boo" +
+                        "lean)");
+    }
+
+    @Test
+    public void boolPrimitiveFromArrayOfObject() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json array value: [{\"red\":255,\"g" +
+                        "reen\":...\nUnable to parse json array value to boolean: [{\"red\":255,\"green\":...");
+    }
+
+    @Test
+    public void boolPrimitiveFromArrayOfString() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json array value: [\"Klaatu\",\"bar" +
+                        "ada\",\"...\nUnable to parse json array value to boolean: [\"Klaatu\",\"barada\",\"...");
+    }
+
+    @Test
+    public void boolPrimitiveFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json array value: [2,3,5,7,11,13" +
+                        ",17,19...\nUnable to parse json array value to boolean: [2,3,5,7,11,13,17,19...");
+    }
+
+    @Test
+    public void boolPrimitiveFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : [true,false,true,true,false] }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json array value: [true,false,tr" +
+                        "ue,tru...\nUnable to parse json array value to boolean: [true,false,true,tru...");
+    }
+
+    @Test
+    public void enumFromObject() throws Exception {
+        assertMessage("{ \"unit\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json object value: {\"red\":255,\"green\":1." +
+                        "..\nUnable to map json object value to class java.lang.String: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void enumFromString() throws Exception {
+        assertMessage("{ \"unit\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json string value: \"Supercalifragilisti." +
+                        "..\nIllegal class java.util.concurrent.TimeUnit enum value: Supercalifragilisticexpialidocious, known" +
+                        " values: [MILLISECONDS, MICROSECONDS, HOURS, SECONDS, NANOSECONDS, DAYS, MINUTES]");
+    }
+
+    @Test
+    public void enumFromNumber() throws Exception {
+        assertMessage("{ \"unit\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json numeric value: 122333444455555.6666" +
+                        "...\nIllegal class java.util.concurrent.TimeUnit enum value: 122333444455555.666666777777788888888, k" +
+                        "nown values: [MILLISECONDS, MICROSECONDS, HOURS, SECONDS, NANOSECONDS, DAYS, MINUTES]");
+    }
+
+    @Test
+    public void enumFromBoolean() throws Exception {
+        assertMessage("{ \"unit\" : true }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json boolean value: true\nIllegal class j" +
+                        "ava.util.concurrent.TimeUnit enum value: true, known values: [MILLISECONDS, MICROSECONDS, HOURS, SEC" +
+                        "ONDS, NANOSECONDS, DAYS, MINUTES]");
+    }
+
+    @Test
+    public void enumFromArrayOfObject() throws Exception {
+        assertMessage("{ \"unit\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json array value: [{\"red\":255,\"green\":.." +
+                        ".\nclass java.lang.String does not support json array value: [{\"red\":255,\"green\":...");
+    }
+
+    @Test
+    public void enumFromArrayOfString() throws Exception {
+        assertMessage("{ \"unit\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json array value: [\"Klaatu\",\"barada\",\".." +
+                        ".\nclass java.lang.String does not support json array value: [\"Klaatu\",\"barada\",\"...");
+    }
+
+    @Test
+    public void enumFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"unit\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json array value: [2,3,5,7,11,13,17,19.." +
+                        ".\nclass java.lang.String does not support json array value: [2,3,5,7,11,13,17,19...");
+    }
+
+    @Test
+    public void enumFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"unit\" : [true,false,true,true,false] }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json array value: [true,false,true,tru.." +
+                        ".\nclass java.lang.String does not support json array value: [true,false,true,tru...");
+    }
+
+    @Test
+    public void dateFromObject() throws Exception {
+        assertMessage("{ \"date\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'date' of type Date cannot be mapped to json object value: {\"red\":255,\"green\":1...\nU" +
+                        "nable to map json object value to class java.lang.String: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void dateFromString() throws Exception {
+        assertMessage("{ \"date\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'date' of type Date cannot be mapped to json string value: \"Supercalifragilisti...\nT" +
+                        "ext 'Supercalifragilisticexpialidocious' could not be parsed at index 0");
+    }
+
+    @Test
+    public void dateFromNumber() throws Exception {
+        assertMessage("{ \"date\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'date' of type Date cannot be mapped to json numeric value: 122333444455555.6666...\n" +
+                        "Text '122333444455555.666666777777788888888' could not be parsed at index 0");
+    }
+
+    @Test
+    public void dateFromBoolean() throws Exception {
+        assertMessage("{ \"date\" : true }",
+                "Widget property 'date' of type Date cannot be mapped to json boolean value: true\nText 'true' could n" +
+                        "ot be parsed at index 0");
+    }
+
+    @Test
+    public void dateFromArrayOfObject() throws Exception {
+        assertMessage("{ \"date\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'date' of type Date cannot be mapped to json array value: [{\"red\":255,\"green\":...\ncl" +
+                        "ass java.lang.String does not support json array value: [{\"red\":255,\"green\":...");
+    }
+
+    @Test
+    public void dateFromArrayOfString() throws Exception {
+        assertMessage("{ \"date\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'date' of type Date cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"...\ncl" +
+                        "ass java.lang.String does not support json array value: [\"Klaatu\",\"barada\",\"...");
+    }
+
+    @Test
+    public void dateFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"date\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'date' of type Date cannot be mapped to json array value: [2,3,5,7,11,13,17,19...\ncl" +
+                        "ass java.lang.String does not support json array value: [2,3,5,7,11,13,17,19...");
+    }
+
+    @Test
+    public void dateFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"date\" : [true,false,true,true,false] }",
+                "Widget property 'date' of type Date cannot be mapped to json array value: [true,false,true,tru...\ncl" +
+                        "ass java.lang.String does not support json array value: [true,false,true,tru...");
+    }
+
+    @Test
+    public void arrayOfObjectFromObject() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json object value: {\"red\":255,\"g" +
+                        "reen\":1...\nColor[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfObjectFromString() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json string value: \"Supercalifra" +
+                        "gilisti...\nMissing a Converter for type class [Lorg.apache.johnzon.jsonb.DeserializationExceptionMes" +
+                        "sagesTest$Color; to convert the JSON String 'Supercalifragilisticexpialidocious' . Please register a" +
+                        " custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfObjectFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json numeric value: 122333444455" +
+                        "555.6666...\nUnable to parse json numeric value to class [Lorg.apache.johnzon.jsonb.DeserializationEx" +
+                        "ceptionMessagesTest$Color;: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfObjectFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : true }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json boolean value: true\nUnable " +
+                        "to parse json boolean value to class [Lorg.apache.johnzon.jsonb.DeserializationExceptionMessagesTest" +
+                        "$Color;: true");
+    }
+
+    @Test
+    public void arrayOfObjectFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json array value: [\"Klaatu\",\"bar" +
+                        "ada\",\"...\nMissing a Converter for type class org.apache.johnzon.jsonb.DeserializationExceptionMessag" +
+                        "esTest$Color to convert the JSON String 'Klaatu' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfObjectFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json array value: [2,3,5,7,11,13" +
+                        ",17,19...\nUnable to parse json numeric value to class org.apache.johnzon.jsonb.DeserializationExcept" +
+                        "ionMessagesTest$Color: 2");
+    }
+
+    @Test
+    public void arrayOfObjectFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json array value: [true,false,tr" +
+                        "ue,tru...\nUnable to parse json boolean value to class org.apache.johnzon.jsonb.DeserializationExcept" +
+                        "ionMessagesTest$Color: true");
+    }
+
+    @Test
+    public void arrayOfStringFromObject() throws Exception {
+        assertMessage("{ \"arrayOfString\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json object value: {\"red\":255,\"" +
+                        "green\":1...\nString[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfStringFromString() throws Exception {
+        assertMessage("{ \"arrayOfString\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json string value: \"Supercalifr" +
+                        "agilisti...\nMissing a Converter for type class [Ljava.lang.String; to convert the JSON String 'Super" +
+                        "califragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfStringFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfString\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json numeric value: 12233344445" +
+                        "5555.6666...\nUnable to parse json numeric value to class [Ljava.lang.String;: 122333444455555.6666.." +
+                        ".");
+    }
+
+    @Test
+    public void arrayOfStringFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfString\" : true }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json boolean value: true\nUnable" +
+                        " to parse json boolean value to class [Ljava.lang.String;: true");
+    }
+
+    @Test
+    public void arrayOfStringFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfString\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json array value: [{\"red\":255,\"" +
+                        "green\":...\nUnable to map json object value to class java.lang.String: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfStringFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"arrayOfString\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json array value: [2,3,5,7,11,1" +
+                        "3,17,19...\nUnable to parse json numeric value to class java.lang.String: 2");
+    }
+
+    @Test
+    public void arrayOfStringFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfString\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json array value: [true,false,t" +
+                        "rue,tru...\nUnable to parse json boolean value to class java.lang.String: true");
+    }
+
+    @Test
+    public void arrayOfNumberFromObject() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json object value: {\"red\":255,\"" +
+                        "green\":1...\nNumber[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfNumberFromString() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json string value: \"Supercalifr" +
+                        "agilisti...\nMissing a Converter for type class [Ljava.lang.Number; to convert the JSON String 'Super" +
+                        "califragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfNumberFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json numeric value: 12233344445" +
+                        "5555.6666...\nUnable to parse json numeric value to class [Ljava.lang.Number;: 122333444455555.6666.." +
+                        ".");
+    }
+
+    @Test
+    public void arrayOfNumberFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : true }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json boolean value: true\nUnable" +
+                        " to parse json boolean value to class [Ljava.lang.Number;: true");
+    }
+
+    @Test
+    public void arrayOfNumberFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json array value: [{\"red\":255,\"" +
+                        "green\":...\nNumber cannot be constructed to deserialize json object value: {\"red\":255,\"green\":1...\nja" +
+                        "va.lang.InstantiationException");
+    }
+
+    @Test
+    public void arrayOfNumberFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json array value: [\"Klaatu\",\"ba" +
+                        "rada\",\"...\nMissing a Converter for type class java.lang.Number to convert the JSON String 'Klaatu' ." +
+                        " Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfNumberFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json array value: [true,false,t" +
+                        "rue,tru...\nUnable to parse json boolean value to class java.lang.Number: true");
+    }
+
+    @Test
+    public void arrayOfBooleanFromObject() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json object value: {\"red\":255" +
+                        ",\"green\":1...\nBoolean[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfBooleanFromString() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json string value: \"Supercali" +
+                        "fragilisti...\nMissing a Converter for type class [Ljava.lang.Boolean; to convert the JSON String 'Su" +
+                        "percalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfBooleanFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json numeric value: 122333444" +
+                        "455555.6666...\nUnable to parse json numeric value to class [Ljava.lang.Boolean;: 122333444455555.666" +
+                        "6...");
+    }
+
+    @Test
+    public void arrayOfBooleanFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : true }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json boolean value: true\nUnab" +
+                        "le to parse json boolean value to class [Ljava.lang.Boolean;: true");
+    }
+
+    @Test
+    public void arrayOfBooleanFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json array value: [{\"red\":255" +
+                        ",\"green\":...\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfBooleanFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json array value: [\"Klaatu\",\"" +
+                        "barada\",\"...\nUnable to parse json string value to boolean: \"Klaatu\"");
+    }
+
+    @Test
+    public void arrayOfBooleanFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json array value: [2,3,5,7,11" +
+                        ",13,17,19...\nUnable to parse json numeric value to boolean: 2");
+    }
+
+    @Test
+    public void arrayOfIntFromObject() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json object value: {\"red\":255,\"green\"" +
+                        ":1...\nint[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfIntFromString() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json string value: \"Supercalifragilis" +
+                        "ti...\nMissing a Converter for type class [I to convert the JSON String 'Supercalifragilisticexpialid" +
+                        "ocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfIntFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json numeric value: 122333444455555.6" +
+                        "666...\nUnable to parse json numeric value to class [I: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfIntFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : true }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json boolean value: true\nUnable to pa" +
+                        "rse json boolean value to class [I: true");
+    }
+
+    @Test
+    public void arrayOfIntFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [{\"red\":255,\"green\"" +
+                        ":...\nUnable to map json object value to int: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfIntFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [\"Klaatu\",\"barada\"," +
+                        "\"...\nMissing a Converter for type int to convert the JSON String 'Klaatu' . Please register a custom" +
+                        " converter for it.");
+    }
+
+    @Test
+    public void arrayOfIntFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [true,false,true,tr" +
+                        "u...\nUnable to parse json boolean value to int: true");
+    }
+
+    @Test
+    public void arrayOfIntFromArrayOfNull() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : [null,null,null,null,null,null] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [null,null,null,nul" +
+                        "l...\njson array mapped to int[] has null value at index 0");
+    }
+
+    @Test
+    public void arrayOfByteFromObject() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json object value: {\"red\":255,\"gree" +
+                        "n\":1...\nbyte[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfByteFromString() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json string value: \"Supercalifragil" +
+                        "isti...\nMissing a Converter for type class [B to convert the JSON String 'Supercalifragilisticexpial" +
+                        "idocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfByteFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json numeric value: 122333444455555" +
+                        ".6666...\nUnable to parse json numeric value to class [B: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfByteFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : true }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json boolean value: true\nUnable to " +
+                        "parse json boolean value to class [B: true");
+    }
+
+    @Test
+    public void arrayOfByteFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json array value: [{\"red\":255,\"gree" +
+                        "n\":...\nUnable to map json object value to byte: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfByteFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json array value: [\"Klaatu\",\"barada" +
+                        "\",\"...\nMissing a Converter for type byte to convert the JSON String 'Klaatu' . Please register a cus" +
+                        "tom converter for it.");
+    }
+
+    @Test
+    public void arrayOfByteFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json array value: [true,false,true," +
+                        "tru...\nUnable to parse json boolean value to byte: true");
+    }
+
+    @Test
+    public void arrayOfCharFromObject() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json object value: {\"red\":255,\"gree" +
+                        "n\":1...\nchar[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfCharFromString() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json string value: \"Supercalifragil" +
+                        "isti...\nMissing a Converter for type class [C to convert the JSON String 'Supercalifragilisticexpial" +
+                        "idocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfCharFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json numeric value: 122333444455555" +
+                        ".6666...\nUnable to parse json numeric value to class [C: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfCharFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : true }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json boolean value: true\nUnable to " +
+                        "parse json boolean value to class [C: true");
+    }
+
+    @Test
+    public void arrayOfCharFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json array value: [{\"red\":255,\"gree" +
+                        "n\":...\nCannot cast org.apache.johnzon.core.JsonObjectImpl to javax.json.JsonString");
+    }
+
+    @Test
+    public void arrayOfCharFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json array value: [true,false,true," +
+                        "tru...\nCannot cast javax.json.JsonValue$2 to javax.json.JsonString");
+    }
+
+    @Test
+    public void arrayOfShortFromObject() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json object value: {\"red\":255,\"gr" +
+                        "een\":1...\nshort[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfShortFromString() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json string value: \"Supercalifrag" +
+                        "ilisti...\nMissing a Converter for type class [S to convert the JSON String 'Supercalifragilisticexpi" +
+                        "alidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfShortFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json numeric value: 1223334444555" +
+                        "55.6666...\nUnable to parse json numeric value to class [S: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfShortFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : true }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json boolean value: true\nUnable t" +
+                        "o parse json boolean value to class [S: true");
+    }
+
+    @Test
+    public void arrayOfShortFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json array value: [{\"red\":255,\"gr" +
+                        "een\":...\nUnable to map json object value to short: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfShortFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json array value: [\"Klaatu\",\"bara" +
+                        "da\",\"...\nMissing a Converter for type short to convert the JSON String 'Klaatu' . Please register a " +
+                        "custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfShortFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json array value: [true,false,tru" +
+                        "e,tru...\nUnable to parse json boolean value to short: true");
+    }
+
+    @Test
+    public void arrayOfLongFromObject() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json object value: {\"red\":255,\"gree" +
+                        "n\":1...\nlong[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfLongFromString() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json string value: \"Supercalifragil" +
+                        "isti...\nMissing a Converter for type class [J to convert the JSON String 'Supercalifragilisticexpial" +
+                        "idocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfLongFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json numeric value: 122333444455555" +
+                        ".6666...\nUnable to parse json numeric value to class [J: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfLongFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : true }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json boolean value: true\nUnable to " +
+                        "parse json boolean value to class [J: true");
+    }
+
+    @Test
+    public void arrayOfLongFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json array value: [{\"red\":255,\"gree" +
+                        "n\":...\nUnable to map json object value to long: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfLongFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json array value: [\"Klaatu\",\"barada" +
+                        "\",\"...\nMissing a Converter for type long to convert the JSON String 'Klaatu' . Please register a cus" +
+                        "tom converter for it.");
+    }
+
+    @Test
+    public void arrayOfLongFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json array value: [true,false,true," +
+                        "tru...\nUnable to parse json boolean value to long: true");
+    }
+
+    @Test
+    public void arrayOfFloatFromObject() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json object value: {\"red\":255,\"gr" +
+                        "een\":1...\nfloat[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfFloatFromString() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json string value: \"Supercalifrag" +
+                        "ilisti...\nMissing a Converter for type class [F to convert the JSON String 'Supercalifragilisticexpi" +
+                        "alidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfFloatFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json numeric value: 1223334444555" +
+                        "55.6666...\nUnable to parse json numeric value to class [F: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfFloatFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : true }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json boolean value: true\nUnable t" +
+                        "o parse json boolean value to class [F: true");
+    }
+
+    @Test
+    public void arrayOfFloatFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json array value: [{\"red\":255,\"gr" +
+                        "een\":...\nUnable to map json object value to float: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfFloatFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json array value: [\"Klaatu\",\"bara" +
+                        "da\",\"...\nMissing a Converter for type float to convert the JSON String 'Klaatu' . Please register a " +
+                        "custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfFloatFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json array value: [true,false,tru" +
+                        "e,tru...\nUnable to parse json boolean value to float: true");
+    }
+
+    @Test
+    public void arrayOfDoubleFromObject() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json object value: {\"red\":255,\"" +
+                        "green\":1...\ndouble[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfDoubleFromString() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json string value: \"Supercalifr" +
+                        "agilisti...\nMissing a Converter for type class [D to convert the JSON String 'Supercalifragilisticex" +
+                        "pialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfDoubleFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json numeric value: 12233344445" +
+                        "5555.6666...\nUnable to parse json numeric value to class [D: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfDoubleFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : true }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json boolean value: true\nUnable" +
+                        " to parse json boolean value to class [D: true");
+    }
+
+    @Test
+    public void arrayOfDoubleFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json array value: [{\"red\":255,\"" +
+                        "green\":...\nUnable to map json object value to double: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfDoubleFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json array value: [\"Klaatu\",\"ba" +
+                        "rada\",\"...\nMissing a Converter for type double to convert the JSON String 'Klaatu' . Please register" +
+                        " a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfDoubleFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json array value: [true,false,t" +
+                        "rue,tru...\nUnable to parse json boolean value to double: true");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromObject() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json object value: {" +
+                        "\"red\":255,\"green\":1...\nboolean[] array not a suitable datatype for json object value: {\"red\":255,\"gr" +
+                        "een\":1...");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromString() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json string value: \"" +
+                        "Supercalifragilisti...\nMissing a Converter for type class [Z to convert the JSON String 'Supercalifr" +
+                        "agilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json numeric value: " +
+                        "122333444455555.6666...\nUnable to parse json numeric value to class [Z: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : true }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json boolean value: " +
+                        "true\nUnable to parse json boolean value to class [Z: true");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [{" +
+                        "\"red\":255,\"green\":...\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [\"" +
+                        "Klaatu\",\"barada\",\"...\nUnable to parse json string value to boolean: \"Klaatu\"");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [2" +
+                        ",3,5,7,11,13,17,19...\nUnable to parse json numeric value to boolean: 2");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromArrayOfNull() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : [null,null,null,null,null,null] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [n" +
+                        "ull,null,null,null...\njson array mapped to boolean[] has null value at index 0");
+    }
+
+    @Test
+    public void listOfObjectFromObject() throws Exception {
+        assertMessage("{ \"listOfObject\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json object value: {\"red\":255" +
+                        ",\"green\":1...\nUnable to map json object value to java.util.List<org.apache.johnzon.jsonb.Deserializa" +
+                        "tionExceptionMessagesTest$Color>: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void listOfObjectFromString() throws Exception {
+        assertMessage("{ \"listOfObject\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json string value: \"Supercali" +
+                        "fragilisti...\nMissing a Converter for type interface java.util.List to convert the JSON String 'Supe" +
+                        "rcalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfObjectFromNumber() throws Exception {
+        assertMessage("{ \"listOfObject\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json numeric value: 122333444" +
+                        "455555.6666...\nUnable to parse json numeric value to java.util.List<org.apache.johnzon.jsonb.Deseria" +
+                        "lizationExceptionMessagesTest$Color>: 122333444455555.6666...");
+    }
+
+    @Test
+    public void listOfObjectFromBoolean() throws Exception {
+        assertMessage("{ \"listOfObject\" : true }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json boolean value: true\nUnab" +
+                        "le to parse json boolean value to java.util.List<org.apache.johnzon.jsonb.DeserializationExceptionMe" +
+                        "ssagesTest$Color>: true");
+    }
+
+    @Test
+    public void listOfObjectFromArrayOfString() throws Exception {
+        assertMessage("{ \"listOfObject\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json array value: [\"Klaatu\",\"" +
+                        "barada\",\"...\nMissing a Converter for type class org.apache.johnzon.jsonb.DeserializationExceptionMes" +
+                        "sagesTest$Color to convert the JSON String 'Klaatu' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfObjectFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"listOfObject\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json array value: [2,3,5,7,11" +
+                        ",13,17,19...\nUnable to parse json numeric value to class org.apache.johnzon.jsonb.DeserializationExc" +
+                        "eptionMessagesTest$Color: 2");
+    }
+
+    @Test
+    public void listOfObjectFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"listOfObject\" : [true,false,true,true,false] }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json array value: [true,false" +
+                        ",true,tru...\nUnable to parse json boolean value to class org.apache.johnzon.jsonb.DeserializationExc" +
+                        "eptionMessagesTest$Color: true");
+    }
+
+    @Test
+    public void listOfStringFromObject() throws Exception {
+        assertMessage("{ \"listOfString\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json object value: {\"red\":25" +
+                        "5,\"green\":1...\nUnable to map json object value to java.util.List<java.lang.String>: {\"red\":255,\"gree" +
+                        "n\":1...");
+    }
+
+    @Test
+    public void listOfStringFromString() throws Exception {
+        assertMessage("{ \"listOfString\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json string value: \"Supercal" +
+                        "ifragilisti...\nMissing a Converter for type interface java.util.List to convert the JSON String 'Sup" +
+                        "ercalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfStringFromNumber() throws Exception {
+        assertMessage("{ \"listOfString\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json numeric value: 12233344" +
+                        "4455555.6666...\nUnable to parse json numeric value to java.util.List<java.lang.String>: 122333444455" +
+                        "555.6666...");
+    }
+
+    @Test
+    public void listOfStringFromBoolean() throws Exception {
+        assertMessage("{ \"listOfString\" : true }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json boolean value: true\nUna" +
+                        "ble to parse json boolean value to java.util.List<java.lang.String>: true");
+    }
+
+    @Test
+    public void listOfStringFromArrayOfObject() throws Exception {
+        assertMessage("{ \"listOfString\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json array value: [{\"red\":25" +
+                        "5,\"green\":...\nUnable to map json object value to class java.lang.String: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void listOfStringFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"listOfString\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json array value: [2,3,5,7,1" +
+                        "1,13,17,19...\nUnable to parse json numeric value to class java.lang.String: 2");
+    }
+
+    @Test
+    public void listOfStringFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"listOfString\" : [true,false,true,true,false] }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json array value: [true,fals" +
+                        "e,true,tru...\nUnable to parse json boolean value to class java.lang.String: true");
+    }
+
+    @Test
+    public void listOfNumberFromObject() throws Exception {
+        assertMessage("{ \"listOfNumber\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json object value: {\"red\":25" +
+                        "5,\"green\":1...\nUnable to map json object value to java.util.List<java.lang.Number>: {\"red\":255,\"gree" +
+                        "n\":1...");
+    }
+
+    @Test
+    public void listOfNumberFromString() throws Exception {
+        assertMessage("{ \"listOfNumber\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json string value: \"Supercal" +
+                        "ifragilisti...\nMissing a Converter for type interface java.util.List to convert the JSON String 'Sup" +
+                        "ercalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfNumberFromNumber() throws Exception {
+        assertMessage("{ \"listOfNumber\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json numeric value: 12233344" +
+                        "4455555.6666...\nUnable to parse json numeric value to java.util.List<java.lang.Number>: 122333444455" +
+                        "555.6666...");
+    }
+
+    @Test
+    public void listOfNumberFromBoolean() throws Exception {
+        assertMessage("{ \"listOfNumber\" : true }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json boolean value: true\nUna" +
+                        "ble to parse json boolean value to java.util.List<java.lang.Number>: true");
+    }
+
+    @Test
+    public void listOfNumberFromArrayOfObject() throws Exception {
+        assertMessage("{ \"listOfNumber\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json array value: [{\"red\":25" +
+                        "5,\"green\":...\nNumber cannot be constructed to deserialize json object value: {\"red\":255,\"green\":1..." +
+                        "\njava.lang.InstantiationException");
+    }
+
+    @Test
+    public void listOfNumberFromArrayOfString() throws Exception {
+        assertMessage("{ \"listOfNumber\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json array value: [\"Klaatu\"," +
+                        "\"barada\",\"...\nMissing a Converter for type class java.lang.Number to convert the JSON String 'Klaatu" +
+                        "' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfNumberFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"listOfNumber\" : [true,false,true,true,false] }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json array value: [true,fals" +
+                        "e,true,tru...\nUnable to parse json boolean value to class java.lang.Number: true");
+    }
+
+    @Test
+    public void listOfBooleanFromObject() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json object value: {\"red\":" +
+                        "255,\"green\":1...\nUnable to map json object value to java.util.List<java.lang.Boolean>: {\"red\":255,\"g" +
+                        "reen\":1...");
+    }
+
+    @Test
+    public void listOfBooleanFromString() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json string value: \"Superc" +
+                        "alifragilisti...\nMissing a Converter for type interface java.util.List to convert the JSON String 'S" +
+                        "upercalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfBooleanFromNumber() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json numeric value: 122333" +
+                        "444455555.6666...\nUnable to parse json numeric value to java.util.List<java.lang.Boolean>: 122333444" +
+                        "455555.6666...");
+    }
+
+    @Test
+    public void listOfBooleanFromBoolean() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : true }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json boolean value: true\nU" +
+                        "nable to parse json boolean value to java.util.List<java.lang.Boolean>: true");
+    }
+
+    @Test
+    public void listOfBooleanFromArrayOfObject() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json array value: [{\"red\":" +
+                        "255,\"green\":...\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void listOfBooleanFromArrayOfString() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json array value: [\"Klaatu" +
+                        "\",\"barada\",\"...\nUnable to parse json string value to boolean: \"Klaatu\"");
+    }
+
+    @Test
+    public void listOfBooleanFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json array value: [2,3,5,7" +
+                        ",11,13,17,19...\nUnable to parse json numeric value to boolean: 2");
+    }
+
+    private void assertMessage(final String json, final String expected) throws Exception {
+        ExceptionAsserts.fromJson(json, Widget.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertMessage(expected);
+    }
+
+    public static class Widget {
+        private Color[] arrayOfObject;
+        private String[] arrayOfString;
+        private Number[] arrayOfNumber;
+        private int[] arrayOfInt;
+        private byte[] arrayOfByte;
+        private char[] arrayOfChar;
+        private short[] arrayOfShort;
+        private long[] arrayOfLong;
+        private float[] arrayOfFloat;
+        private double[] arrayOfDouble;
+        private Boolean[] arrayOfBoolean;
+        private boolean[] arrayOfBooleanPrimitive;
+        private List<Color> listOfObject;
+        private List<String> listOfString;
+        private List<Number> listOfNumber;
+        private List<Boolean> listOfBoolean;
+        private Color object;
+        private String string;
+        private Integer number;
+        private int intPrimitive;
+        private Boolean bool;
+        private boolean boolPrimitive;
+        private Date date;
+        private TimeUnit unit;
+
+        public Color[] getArrayOfObject() {
+            return arrayOfObject;
+        }
+
+        public void setArrayOfObject(final Color[] arrayOfObject) {
+            this.arrayOfObject = arrayOfObject;
+        }
+
+        public String[] getArrayOfString() {
+            return arrayOfString;
+        }
+
+        public void setArrayOfString(final String[] arrayOfString) {
+            this.arrayOfString = arrayOfString;
+        }
+
+        public Number[] getArrayOfNumber() {
+            return arrayOfNumber;
+        }
+
+        public void setArrayOfNumber(final Number[] arrayOfNumber) {
+            this.arrayOfNumber = arrayOfNumber;
+        }
+
+        public int[] getArrayOfInt() {
+            return arrayOfInt;
+        }
+
+        public void setArrayOfInt(final int[] arrayOfInt) {
+            this.arrayOfInt = arrayOfInt;
+        }
+
+        public byte[] getArrayOfByte() {
+            return arrayOfByte;
+        }
+
+        public void setArrayOfByte(final byte[] arrayOfByte) {
+            this.arrayOfByte = arrayOfByte;
+        }
+
+        public char[] getArrayOfChar() {
+            return arrayOfChar;
+        }
+
+        public void setArrayOfChar(final char[] arrayOfChar) {
+            this.arrayOfChar = arrayOfChar;
+        }
+
+        public short[] getArrayOfShort() {
+            return arrayOfShort;
+        }
+
+        public void setArrayOfShort(final short[] arrayOfShort) {
+            this.arrayOfShort = arrayOfShort;
+        }
+
+        public long[] getArrayOfLong() {
+            return arrayOfLong;
+        }
+
+        public void setArrayOfLong(final long[] arrayOfLong) {
+            this.arrayOfLong = arrayOfLong;
+        }
+
+        public float[] getArrayOfFloat() {
+            return arrayOfFloat;
+        }
+
+        public void setArrayOfFloat(final float[] arrayOfFloat) {
+            this.arrayOfFloat = arrayOfFloat;
+        }
+
+        public double[] getArrayOfDouble() {
+            return arrayOfDouble;
+        }
+
+        public void setArrayOfDouble(final double[] arrayOfDouble) {
+            this.arrayOfDouble = arrayOfDouble;
+        }
+
+        public Boolean[] getArrayOfBoolean() {
+            return arrayOfBoolean;
+        }
+
+        public void setArrayOfBoolean(final Boolean[] arrayOfBoolean) {
+            this.arrayOfBoolean = arrayOfBoolean;
+        }
+
+        public boolean[] getArrayOfBooleanPrimitive() {
+            return arrayOfBooleanPrimitive;
+        }
+
+        public void setArrayOfBooleanPrimitive(final boolean[] arrayOfBooleanPrimitive) {
+            this.arrayOfBooleanPrimitive = arrayOfBooleanPrimitive;
+        }
+
+        public List<Color> getListOfObject() {
+            return listOfObject;
+        }
+
+        public void setListOfObject(final List<Color> listOfObject) {
+            this.listOfObject = listOfObject;
+        }
+
+        public List<String> getListOfString() {
+            return listOfString;
+        }
+
+        public void setListOfString(final List<String> listOfString) {
+            this.listOfString = listOfString;
+        }
+
+        public List<Number> getListOfNumber() {
+            return listOfNumber;
+        }
+
+        public void setListOfNumber(final List<Number> listOfNumber) {
+            this.listOfNumber = listOfNumber;
+        }
+
+        public List<Boolean> getListOfBoolean() {
+            return listOfBoolean;
+        }
+
+        public void setListOfBoolean(final List<Boolean> listOfBoolean) {
+            this.listOfBoolean = listOfBoolean;
+        }
+
+        public Color getObject() {
+            return object;
+        }
+
+        public void setObject(final Color object) {
+            this.object = object;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+
+        public Integer getNumber() {
+            return number;
+        }
+
+        public void setNumber(final Integer number) {
+            this.number = number;
+        }
+
+        public int getIntPrimitive() {
+            return intPrimitive;
+        }
+
+        public void setIntPrimitive(final int intPrimitive) {
+            this.intPrimitive = intPrimitive;
+        }
+
+        public Boolean getBool() {
+            return bool;
+        }
+
+        public void setBool(final Boolean bool) {
+            this.bool = bool;
+        }
+
+        public boolean isBoolPrimitive() {
+            return boolPrimitive;
+        }
+
+        public void setBoolPrimitive(final boolean boolPrimitive) {
+            this.boolPrimitive = boolPrimitive;
+        }
+
+        public Date getDate() {
+            return date;
+        }
+
+        public void setDate(final Date date) {
+            this.date = date;
+        }
+
+        public TimeUnit getUnit() {
+            return unit;
+        }
+
+        public void setUnit(final TimeUnit unit) {
+            this.unit = unit;
+        }
+    }
+
+    public static class Color {
+        int red;
+        int green;
+        int blue;
+
+        public Color() {
+        }
+
+        public int getRed() {
+            return red;
+        }
+
+        public void setRed(final int red) {
+            this.red = red;
+        }
+
+        public int getGreen() {
+            return green;
+        }
+
+        public void setGreen(final int green) {
+            this.green = green;
+        }
+
+        public int getBlue() {
+            return blue;
+        }
+
+        public void setBlue(final int blue) {
+            this.blue = blue;
+        }
+    }
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ExceptionAsserts.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ExceptionAsserts.java
new file mode 100644
index 0000000..777ea0b
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/ExceptionAsserts.java
@@ -0,0 +1,123 @@
+/*
+ * 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.johnzon.jsonb;
+
+import org.junit.Assert;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.json.bind.JsonbConfig;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Type;
+import java.util.concurrent.Callable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ExceptionAsserts {
+
+    private final Throwable throwable;
+
+    public ExceptionAsserts(final Throwable throwable) {
+        this.throwable = throwable;
+    }
+
+    public <T extends Throwable> ExceptionAsserts assertInstanceOf(final Class<T> expected) {
+        final String message = String.format("%s not an instance of %s",
+                throwable.getClass().getSimpleName(),
+                expected.getSimpleName());
+        assertTrue(message, expected.isAssignableFrom(throwable.getClass()));
+        return this;
+    }
+
+    public ExceptionAsserts assertSame(final Throwable expected) {
+        Assert.assertSame(expected, throwable);
+        return this;
+    }
+
+    public ExceptionAsserts assertCauseChain(final Throwable expected) {
+        Throwable cause = throwable;
+        while ((cause = cause.getCause()) != null) {
+            if (cause == expected) {
+                return this;
+            }
+        }
+
+        throw new AssertionError("Throwable " + throwable.getClass().getSimpleName() +
+                " cause chain does not contain exception:" + expected.getMessage(), throwable);
+    }
+
+    public ExceptionAsserts assertMessage(final String expected) {
+        assertEquals(expected, throwable.getMessage());
+        return this;
+    }
+
+    /**
+     * Useful for debugging tests
+     */
+    public ExceptionAsserts printStackTrace() {
+        throwable.printStackTrace();
+        return this;
+    }
+
+    public Throwable getThrowable() {
+        return throwable;
+    }
+
+    public static ExceptionAsserts from(final Runnable runnable) {
+        return from(runnable);
+    }
+
+    public static ExceptionAsserts from(final Callable<?> runnable) {
+        try {
+
+            runnable.call();
+
+            throw new AssertionError("No exception occurred");
+
+        } catch (AssertionError assertionError) {
+            throw assertionError;
+        } catch (Throwable throwable) {
+            return new ExceptionAsserts(throwable);
+        }
+    }
+
+    public static ExceptionAsserts fromJson(final String json, final Type clazz) {
+
+        final JsonbConfig config = new JsonbConfig();
+        config.setProperty("johnzon.snippetMaxLength", 20);
+
+        return from(() -> {
+            try (final Jsonb jsonb = JsonbBuilder.create(config)) {
+                return jsonb.fromJson(json, clazz);
+            }
+        });
+    }
+
+    public static ExceptionAsserts toJson(final Object object) {
+
+        final JsonbConfig config = new JsonbConfig();
+        config.setProperty("johnzon.snippetMaxLength", 20);
+
+        return from(() -> {
+            try (final Jsonb jsonb = JsonbBuilder.create(config)) {
+                jsonb.toJson(object, new ByteArrayOutputStream());
+                return null;
+            }
+        });
+    }
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbAdapterExceptionsTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbAdapterExceptionsTest.java
new file mode 100644
index 0000000..84a1998
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbAdapterExceptionsTest.java
@@ -0,0 +1,261 @@
+/*
+ * 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.johnzon.jsonb;
+
+import org.junit.Test;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.json.bind.JsonbConfig;
+import javax.json.bind.JsonbException;
+import javax.json.bind.adapter.JsonbAdapter;
+import javax.json.bind.annotation.JsonbTypeAdapter;
+import java.util.concurrent.Callable;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class JsonbAdapterExceptionsTest {
+
+    private static final Exception ADAPT_TO_JSON_EXCEPTION = new Exception("I am user, hear me roar");
+    private static final Exception ADAPT_FROM_JSON_EXCEPTION = new Exception("I am user, hear me roar");
+    private static final Exception CONSTRUCTOR_EXCEPTION = new Exception("I am user, hear me roar");
+
+    @Test
+    public void adaptToJsonRuntimeException() {
+
+        final Object object = new WidgetWithFailedAdapter(new Color("red"));
+
+        ExceptionAsserts.toJson(object)
+                .assertInstanceOf(JsonbException.class)
+                .assertCauseChain(ADAPT_TO_JSON_EXCEPTION)
+                .assertMessage("I am user, hear me roar");
+    }
+
+    @Test
+    public void adaptFromJsonRuntimeException() {
+        final String json = "{\"color\":{\"red\":2550,\"green\":0,\"blue\":0}}";
+
+        ExceptionAsserts.fromJson(json, WidgetWithFailedAdapter.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertCauseChain(ADAPT_FROM_JSON_EXCEPTION)
+                .assertMessage("WidgetWithFailedAdapter property 'color' of type Color cannot be" +
+                        " mapped to json object value: {\"red\":2550,\"green\":...\n" +
+                        "I am user, hear me roar");
+    }
+
+    @Test
+    public void fromJsonConstructorRuntimeException() {
+        final String json = "{\"color\":{\"red\":2550,\"green\":0,\"blue\":0}}";
+
+        ExceptionAsserts.fromJson(json, WidgetWithFailedConstructorAdapter.class)
+                // TODO Review: shouldn't this be wrapped in a JsonbException?
+                .assertSame(CONSTRUCTOR_EXCEPTION);
+    }
+
+    @Test
+    public void toJsonConstructorRuntimeException() {
+
+        final Object object = new WidgetWithFailedConstructorAdapter(new Color("red"));
+
+        ExceptionAsserts.toJson(object)
+                // TODO Review: shouldn't this be wrapped in a JsonbException?
+                .assertSame(CONSTRUCTOR_EXCEPTION);
+    }
+
+    @Test
+    public void adaptToJsonReturnNull() {
+
+        final Object object = new WidgetWithReturnNullAdapter(new Color("red"));
+
+        ExceptionAsserts.toJson(object)
+                // TODO Review potential symmetry issue: adaptFromJson() can return null, but adaptToJson() cannot
+                .assertInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void adaptFromJsonReturnNull() throws Exception {
+        final String json = "{\"color\":{\"red\":2550,\"green\":0,\"blue\":0}}";
+
+        final JsonbConfig config = new JsonbConfig();
+        config.setProperty("johnzon.snippetMaxLength", 20);
+
+        final WidgetWithReturnNullAdapter widget = ((Callable<WidgetWithReturnNullAdapter>) () -> {
+            try (final Jsonb jsonb = JsonbBuilder.create(config)) {
+                return jsonb.fromJson(json, WidgetWithReturnNullAdapter.class);
+            }
+        }).call();
+
+        assertNotNull(widget);
+        assertNull(widget.getColor());
+    }
+
+
+    public static class FailedAdapter implements JsonbAdapter<Color, RGB> {
+
+        @Override
+        public RGB adaptToJson(final Color color) throws Exception {
+            throw ADAPT_TO_JSON_EXCEPTION;
+        }
+
+        @Override
+        public Color adaptFromJson(final RGB rgb) throws Exception {
+            throw ADAPT_FROM_JSON_EXCEPTION;
+        }
+    }
+
+    public static class FailedConstructorAdapter implements JsonbAdapter<Color, RGB> {
+        public FailedConstructorAdapter() throws Exception {
+            throw CONSTRUCTOR_EXCEPTION;
+        }
+
+        @Override
+        public RGB adaptToJson(final Color color) throws Exception {
+            return null;
+        }
+
+        @Override
+        public Color adaptFromJson(final RGB rgb) throws Exception {
+            return null;
+        }
+    }
+
+    public static class ReturnNullAdapter implements JsonbAdapter<Color, RGB> {
+        @Override
+        public RGB adaptToJson(final Color color) throws Exception {
+            return null;
+        }
+
+        @Override
+        public Color adaptFromJson(final RGB rgb) throws Exception {
+            return null;
+        }
+    }
+
+    public static class WidgetWithReturnNullAdapter {
+        @JsonbTypeAdapter(ReturnNullAdapter.class)
+        private Color color;
+
+        public WidgetWithReturnNullAdapter() {
+        }
+
+        public WidgetWithReturnNullAdapter(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class WidgetWithFailedConstructorAdapter {
+        @JsonbTypeAdapter(FailedConstructorAdapter.class)
+        private Color color;
+
+        public WidgetWithFailedConstructorAdapter() {
+        }
+
+        public WidgetWithFailedConstructorAdapter(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class WidgetWithFailedAdapter {
+        @JsonbTypeAdapter(FailedAdapter.class)
+        private Color color;
+
+        public WidgetWithFailedAdapter() {
+        }
+
+        public WidgetWithFailedAdapter(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class Color {
+        private final String name;
+
+        public Color(final String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    public static class RGB {
+        private int red;
+        private int green;
+        private int blue;
+
+        public RGB() {
+        }
+
+        public RGB(final int red, final int green, final int blue) {
+            this.red = red;
+            this.green = green;
+            this.blue = blue;
+        }
+
+        public int getRed() {
+            return red;
+        }
+
+        public void setRed(final int red) {
+            this.red = red;
+        }
+
+        public int getGreen() {
+            return green;
+        }
+
+        public void setGreen(final int green) {
+            this.green = green;
+        }
+
+        public int getBlue() {
+            return blue;
+        }
+
+        public void setBlue(final int blue) {
+            this.blue = blue;
+        }
+
+    }
+
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanConstructorExceptionsTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanConstructorExceptionsTest.java
new file mode 100644
index 0000000..a395df2
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanConstructorExceptionsTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.johnzon.jsonb;
+
+import org.junit.Test;
+
+import javax.json.bind.JsonbException;
+import java.beans.ConstructorProperties;
+import java.lang.reflect.Type;
+
+public class JsonbBeanConstructorExceptionsTest {
+
+    private static final RuntimeException USER_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void constructor() {
+        ExceptionAsserts.fromJson("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Circle.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertCauseChain(USER_EXCEPTION)
+                .assertMessage("Circle cannot be constructed to deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    @Test
+    public void constructorParametersWithNoAnnotations() {
+        ExceptionAsserts.fromJson("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Square.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertMessage("Square has no suitable constructor or factory.  Cannot deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "Use Johnzon @ConstructorProperties or @JsonbCreator if constructor arguments are needed\n" +
+                        "class org.apache.johnzon.jsonb.JsonbBeanConstructorExceptionsTest$Square not instantiable");
+    }
+
+    @Test
+    public void constructorWithGenerics() {
+
+        final Type type = new Oval<String>(true) {
+        }.getClass().getGenericSuperclass();
+
+        ExceptionAsserts.fromJson("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", type)
+                .assertInstanceOf(JsonbException.class)
+                .assertCauseChain(USER_EXCEPTION)
+                .assertMessage("Oval<String> cannot be constructed to deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    @Test
+    public void constructorProperties() {
+        ExceptionAsserts.fromJson("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Triangle.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertCauseChain(USER_EXCEPTION)
+                .assertMessage("Triangle cannot be constructed to deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    @Test
+    public void noConstructors() {
+        ExceptionAsserts.fromJson("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Sphere.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertMessage("Sphere is an interface and requires an adapter or factory.  Cannot deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "interface org.apache.johnzon.jsonb.JsonbBeanConstructorExceptionsTest$Sphere not instantiable");
+    }
+
+    public static class Circle {
+        private String string;
+
+        public Circle() {
+            throw USER_EXCEPTION;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+    }
+
+    public static class Square {
+        private String string;
+
+        public Square(final String string) {
+            throw USER_EXCEPTION;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+    }
+
+    public static class Oval<T> {
+        private String s;
+
+        public Oval() {
+            throw USER_EXCEPTION;
+        }
+
+        public Oval(final boolean ignored) {
+        }
+    }
+
+    public static class Triangle {
+        private String string;
+
+        @ConstructorProperties("string")
+        public Triangle(final String string) {
+            throw USER_EXCEPTION;
+        }
+    }
+
+    public interface Sphere {
+    }
+
+
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanGetterUserExceptionsTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanGetterUserExceptionsTest.java
new file mode 100644
index 0000000..f3a77e0
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanGetterUserExceptionsTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.johnzon.jsonb;
+
+import org.apache.johnzon.mapper.MapperException;
+import org.junit.Test;
+
+public class JsonbBeanGetterUserExceptionsTest {
+
+    private static final RuntimeException USER_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void object() {
+        ExceptionAsserts.toJson(new Widget())
+                // TODO Review: shouldn't this be JsonbException?
+                .assertInstanceOf(MapperException.class)
+                .assertMessage("Error calling public java.lang.String org.apache.johnzon.jsonb.JsonbBean" +
+                        "GetterUserExceptionsTest$Widget.getString()")
+                .assertCauseChain(USER_EXCEPTION);
+    }
+
+    public static class Widget {
+        private String string;
+
+        public String getString() {
+            throw USER_EXCEPTION;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+    }
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanSetterUserExceptionsTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanSetterUserExceptionsTest.java
new file mode 100644
index 0000000..531276c
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbBeanSetterUserExceptionsTest.java
@@ -0,0 +1,479 @@
+/*
+ * 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.johnzon.jsonb;
+
+import org.junit.Test;
+
+import javax.json.bind.JsonbException;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class JsonbBeanSetterUserExceptionsTest {
+
+    private static final RuntimeException USER_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void object() {
+        assertException("{ \"object\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'object' of type Color cannot be mapped to json object value: {\"red\":255,\"green\":1.." +
+                        ".\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setObjec" +
+                        "t(org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Color)");
+    }
+
+    @Test
+    public void string() {
+        assertException("{ \"string\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'string' of type String cannot be mapped to json string value: \"Supercalifragilisti." +
+                        "..\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setStri" +
+                        "ng(java.lang.String)");
+    }
+
+    @Test
+    public void number() {
+        assertException("{ \"number\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'number' of type Double cannot be mapped to json numeric value: 122333444455555.6666" +
+                        "...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setNum" +
+                        "ber(java.lang.Double)");
+    }
+
+    @Test
+    public void intPrimitive() {
+        assertException("{ \"intPrimitive\" : 42 }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json numeric value: 42\nError calling " +
+                        "public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setIntPrimitive(int)");
+    }
+
+    @Test
+    public void booleanValue() {
+        assertException("{ \"bool\" : true }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json boolean value: true\nError calling pu" +
+                        "blic void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setBool(java.lang.Boolean)");
+    }
+
+    @Test
+    public void boolPrimitive() {
+        assertException("{ \"boolPrimitive\" : true }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json boolean value: true\nError c" +
+                        "alling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setBoolPrimitive(" +
+                        "boolean)");
+    }
+
+    @Test
+    public void enumeration() {
+        assertException("{ \"unit\" : \"SECONDS\" }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json string value: \"SECONDS\"\nError calli" +
+                        "ng public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setUnit(java.util.con" +
+                        "current.TimeUnit)");
+    }
+
+    @Test
+    public void date() {
+        assertException("{ \"date\" : \"2022-05-08T22:04:10.328Z[UTC]\" }",
+                "Widget property 'date' of type Date cannot be mapped to json string value: \"2022-05-08T22:04:10...\n" +
+                        "Error calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setDate(java" +
+                        ".util.Date)");
+    }
+
+    @Test
+    public void arrayOfObject() {
+        assertException("{ \"arrayOfObject\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json array value: [{\"red\":255,\"g" +
+                        "reen\":...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget." +
+                        "setArrayOfObject(org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Color[])");
+    }
+
+    @Test
+    public void arrayOfString() {
+        assertException("{ \"arrayOfString\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json array value: [\"Klaatu\",\"ba" +
+                        "rada\",\"...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget" +
+                        ".setArrayOfString(java.lang.String[])");
+    }
+
+    @Test
+    public void arrayOfNumber() {
+        assertException("{ \"arrayOfNumber\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json array value: [2,3,5,7,11,1" +
+                        "3,17,19...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget" +
+                        ".setArrayOfNumber(java.lang.Number[])");
+    }
+
+    @Test
+    public void arrayOfBoolean() {
+        assertException("{ \"arrayOfBoolean\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json array value: [true,false" +
+                        ",true,tru...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widg" +
+                        "et.setArrayOfBoolean(java.lang.Boolean[])");
+    }
+
+    @Test
+    public void arrayOfInt() {
+        assertException("{ \"arrayOfInt\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [2,3,5,7,11,13,17,1" +
+                        "9...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.setAr" +
+                        "rayOfInt(int[])");
+    }
+
+    @Test
+    public void arrayOfByte() {
+        assertException("{ \"arrayOfByte\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json array value: [2,3,5,7,11,13,17" +
+                        ",19...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.set" +
+                        "ArrayOfByte(byte[])");
+    }
+
+    @Test
+    public void arrayOfChar() {
+        assertException("{ \"arrayOfChar\" : [\"a\",\"a\",\"a\",\"a\",\"a\",\"a\",\"a\",\"a\"] }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json array value: [\"a\",\"a\",\"a\",\"a\"," +
+                        "\"a\"...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.set" +
+                        "ArrayOfChar(char[])");
+    }
+
+    @Test
+    public void arrayOfShort() {
+        assertException("{ \"arrayOfShort\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json array value: [2,3,5,7,11,13," +
+                        "17,19...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.s" +
+                        "etArrayOfShort(short[])");
+    }
+
+    @Test
+    public void arrayOfLong() {
+        assertException("{ \"arrayOfLong\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json array value: [2,3,5,7,11,13,17" +
+                        ",19...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.set" +
+                        "ArrayOfLong(long[])");
+    }
+
+    @Test
+    public void arrayOfFloat() {
+        assertException("{ \"arrayOfFloat\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json array value: [2,3,5,7,11,13," +
+                        "17,19...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget.s" +
+                        "etArrayOfFloat(float[])");
+    }
+
+    @Test
+    public void arrayOfDouble() {
+        assertException("{ \"arrayOfDouble\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json array value: [2,3,5,7,11,1" +
+                        "3,17,19...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widget" +
+                        ".setArrayOfDouble(double[])");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitive() {
+        assertException("{ \"arrayOfBooleanPrimitive\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [t" +
+                        "rue,false,true,tru...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptions" +
+                        "Test$Widget.setArrayOfBooleanPrimitive(boolean[])");
+    }
+
+    @Test
+    public void listOfObject() {
+        assertException("{ \"listOfObject\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json array value: [{\"red\":255" +
+                        ",\"green\":...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Widg" +
+                        "et.setListOfObject(java.util.List)");
+    }
+
+    @Test
+    public void listOfString() {
+        assertException("{ \"listOfString\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json array value: [\"Klaatu\"," +
+                        "\"barada\",\"...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Wid" +
+                        "get.setListOfString(java.util.List)");
+    }
+
+    @Test
+    public void listOfNumber() {
+        assertException("{ \"listOfNumber\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json array value: [2,3,5,7,1" +
+                        "1,13,17,19...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$Wid" +
+                        "get.setListOfNumber(java.util.List)");
+    }
+
+    @Test
+    public void listOfBoolean() {
+        assertException("{ \"listOfBoolean\" : [true,false,true,true,false] }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json array value: [true,fa" +
+                        "lse,true,tru...\nError calling public void org.apache.johnzon.jsonb.JsonbBeanSetterUserExceptionsTest$W" +
+                        "idget.setListOfBoolean(java.util.List)");
+    }
+
+    private void assertException(final String json, final String expected) {
+        ExceptionAsserts.fromJson(json, Widget.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertMessage(expected)
+                .assertCauseChain(USER_EXCEPTION);
+    }
+
+    public static class Widget {
+        private Color[] arrayOfObject;
+        private String[] arrayOfString;
+        private Number[] arrayOfNumber;
+        private int[] arrayOfInt;
+        private byte[] arrayOfByte;
+        private char[] arrayOfChar;
+        private short[] arrayOfShort;
+        private long[] arrayOfLong;
+        private float[] arrayOfFloat;
+        private double[] arrayOfDouble;
+        private Boolean[] arrayOfBoolean;
+        private boolean[] arrayOfBooleanPrimitive;
+        private List<Color> listOfObject;
+        private List<String> listOfString;
+        private List<Number> listOfNumber;
+        private List<Boolean> listOfBoolean;
+        private Color object;
+        private String string;
+        private Double number;
+        private int intPrimitive;
+        private Boolean bool;
+        private boolean boolPrimitive;
+        private Date date;
+        private TimeUnit unit;
+
+        public Color[] getArrayOfObject() {
+            return arrayOfObject;
+        }
+
+        public void setArrayOfObject(final Color[] arrayOfObject) {
+            throw USER_EXCEPTION;
+        }
+
+        public String[] getArrayOfString() {
+            return arrayOfString;
+        }
+
+        public void setArrayOfString(final String[] arrayOfString) {
+            throw USER_EXCEPTION;
+        }
+
+        public Number[] getArrayOfNumber() {
+            return arrayOfNumber;
+        }
+
+        public void setArrayOfNumber(final Number[] arrayOfNumber) {
+            throw USER_EXCEPTION;
+        }
+
+        public int[] getArrayOfInt() {
+            return arrayOfInt;
+        }
+
+        public void setArrayOfInt(final int[] arrayOfint) {
+            throw USER_EXCEPTION;
+        }
+
+        public Boolean[] getArrayOfBoolean() {
+            return arrayOfBoolean;
+        }
+
+        public void setArrayOfBoolean(final Boolean[] arrayOfBoolean) {
+            throw USER_EXCEPTION;
+        }
+
+        public boolean[] getArrayOfBooleanPrimitive() {
+            return arrayOfBooleanPrimitive;
+        }
+
+        public void setArrayOfBooleanPrimitive(final boolean[] arrayOfBooleanPrimitive) {
+            throw USER_EXCEPTION;
+        }
+
+        public Color getObject() {
+            return object;
+        }
+
+        public void setObject(final Color object) {
+            throw USER_EXCEPTION;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            throw USER_EXCEPTION;
+        }
+
+        public Double getNumber() {
+            return number;
+        }
+
+        public void setNumber(final Double number) {
+            throw USER_EXCEPTION;
+        }
+
+        public int getIntPrimitive() {
+            return intPrimitive;
+        }
+
+        public void setIntPrimitive(final int intPrimitive) {
+            throw USER_EXCEPTION;
+        }
+
+        public Boolean getBool() {
+            return bool;
+        }
+
+        public void setBool(final Boolean bool) {
+            throw USER_EXCEPTION;
+        }
+
+        public boolean isBoolPrimitive() {
+            return boolPrimitive;
+        }
+
+        public void setBoolPrimitive(final boolean boolPrimitive) {
+            throw USER_EXCEPTION;
+        }
+
+        public Date getDate() {
+            return date;
+        }
+
+        public void setDate(final Date date) {
+            throw USER_EXCEPTION;
+        }
+
+        public TimeUnit getUnit() {
+            return unit;
+        }
+
+        public void setUnit(final TimeUnit unit) {
+            throw USER_EXCEPTION;
+        }
+
+        public byte[] getArrayOfByte() {
+            return arrayOfByte;
+        }
+
+        public void setArrayOfByte(final byte[] arrayOfByte) {
+            throw USER_EXCEPTION;
+        }
+
+        public char[] getArrayOfChar() {
+            return arrayOfChar;
+        }
+
+        public void setArrayOfChar(final char[] arrayOfChar) {
+            throw USER_EXCEPTION;
+        }
+
+        public short[] getArrayOfShort() {
+            return arrayOfShort;
+        }
+
+        public void setArrayOfShort(final short[] arrayOfShort) {
+            throw USER_EXCEPTION;
+        }
+
+        public long[] getArrayOfLong() {
+            return arrayOfLong;
+        }
+
+        public void setArrayOfLong(final long[] arrayOfLong) {
+            throw USER_EXCEPTION;
+        }
+
+        public float[] getArrayOfFloat() {
+            return arrayOfFloat;
+        }
+
+        public void setArrayOfFloat(final float[] arrayOfFloat) {
+            throw USER_EXCEPTION;
+        }
+
+        public double[] getArrayOfDouble() {
+            return arrayOfDouble;
+        }
+
+        public void setArrayOfDouble(final double[] arrayOfDouble) {
+            throw USER_EXCEPTION;
+        }
+
+        public List<Color> getListOfObject() {
+            return listOfObject;
+        }
+
+        public void setListOfObject(final List<Color> listOfObject) {
+            throw USER_EXCEPTION;
+        }
+
+        public List<String> getListOfString() {
+            return listOfString;
+        }
+
+        public void setListOfString(final List<String> listOfString) {
+            throw USER_EXCEPTION;
+        }
+
+        public List<Number> getListOfNumber() {
+            return listOfNumber;
+        }
+
+        public void setListOfNumber(final List<Number> listOfNumber) {
+            throw USER_EXCEPTION;
+        }
+
+        public List<Boolean> getListOfBoolean() {
+            return listOfBoolean;
+        }
+
+        public void setListOfBoolean(final List<Boolean> listOfBoolean) {
+            throw USER_EXCEPTION;
+        }
+
+    }
+
+    public static class Color {
+        int red;
+        int green;
+        int blue;
+
+        public Color() {
+        }
+
+        public int getRed() {
+            return red;
+        }
+
+        public void setRed(final int red) {
+            this.red = red;
+        }
+
+        public int getGreen() {
+            return green;
+        }
+
+        public void setGreen(final int green) {
+            this.green = green;
+        }
+
+        public int getBlue() {
+            return blue;
+        }
+
+        public void setBlue(final int blue) {
+            this.blue = blue;
+        }
+    }
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbCreatorExceptionsTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbCreatorExceptionsTest.java
new file mode 100644
index 0000000..1500160
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbCreatorExceptionsTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.johnzon.jsonb;
+
+import org.junit.Test;
+
+import javax.json.bind.JsonbException;
+import javax.json.bind.annotation.JsonbCreator;
+import javax.json.bind.annotation.JsonbProperty;
+
+public class JsonbCreatorExceptionsTest {
+
+    private static final RuntimeException CONSTRUCTOR_EXCEPTION = new RuntimeException("I am user, hear me roar");
+    private static final RuntimeException FACTORY_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void constructor() {
+        ExceptionAsserts.fromJson("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Circle.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertCauseChain(CONSTRUCTOR_EXCEPTION)
+                .assertMessage("Circle cannot be constructed to deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+
+    @Test
+    public void factory() {
+        ExceptionAsserts.fromJson("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Square.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertCauseChain(FACTORY_EXCEPTION)
+                .assertMessage("Square cannot be constructed to deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    public static class Circle {
+        private String string;
+
+        @JsonbCreator
+        public Circle(@JsonbProperty("string") final String string) {
+            throw CONSTRUCTOR_EXCEPTION;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+    }
+
+    public static class Square {
+        private String string;
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+
+        @JsonbCreator
+        public static Square square(@JsonbProperty("string") final String string) {
+            throw FACTORY_EXCEPTION;
+        }
+    }
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbSerializerExceptionsTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbSerializerExceptionsTest.java
new file mode 100644
index 0000000..43bc71c
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbSerializerExceptionsTest.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.johnzon.jsonb;
+
+import org.junit.Test;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.JsonbBuilder;
+import javax.json.bind.JsonbConfig;
+import javax.json.bind.JsonbException;
+import javax.json.bind.annotation.JsonbTypeDeserializer;
+import javax.json.bind.annotation.JsonbTypeSerializer;
+import javax.json.bind.serializer.DeserializationContext;
+import javax.json.bind.serializer.JsonbDeserializer;
+import javax.json.bind.serializer.JsonbSerializer;
+import javax.json.bind.serializer.SerializationContext;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonParser;
+import java.lang.reflect.Type;
+import java.util.concurrent.Callable;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class JsonbSerializerExceptionsTest {
+
+    private static final RuntimeException SERIALIZE_EXCEPTION = new RuntimeException("I am user, hear me roar");
+    private static final RuntimeException DESERIALIZE_EXCEPTION = new RuntimeException("I am user, hear me roar");
+    private static final RuntimeException CONSTRUCTOR_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void serializeRuntimeException() {
+
+        final Object object = new WidgetWithFailedSerializer(new Color("red"));
+
+        ExceptionAsserts.toJson(object)
+                // TODO Review: shouldn't this be a JsonbException?
+                .assertSame(SERIALIZE_EXCEPTION);
+    }
+
+    @Test
+    public void deserializeRuntimeException() {
+        final String json = "{\"color\":{\"red\":2550,\"green\":0,\"blue\":0}}";
+
+        ExceptionAsserts.fromJson(json, WidgetWithFailedSerializer.class)
+                .assertInstanceOf(JsonbException.class)
+                .assertCauseChain(DESERIALIZE_EXCEPTION)
+                .assertMessage("WidgetWithFailedSerializer property 'color' of type Color cannot be" +
+                        " mapped to json object value: {\"red\":2550,\"green\":...\n" +
+                        "I am user, hear me roar");
+    }
+
+    @Test
+    public void deserializeConstructorRuntimeException() {
+        final String json = "{\"color\":{\"red\":2550,\"green\":0,\"blue\":0}}";
+
+        ExceptionAsserts.fromJson(json, WidgetWithFailedConstructorSerializer.class)
+                // TODO Review: shouldn't this be wrapped in a JsonbException?
+                .assertSame(CONSTRUCTOR_EXCEPTION);
+    }
+
+    @Test
+    public void serializeConstructorRuntimeException() {
+
+        final Object object = new WidgetWithFailedConstructorSerializer(new Color("red"));
+
+        ExceptionAsserts.toJson(object)
+                // TODO Review: shouldn't this be wrapped in a JsonbException?
+                .assertSame(CONSTRUCTOR_EXCEPTION);
+    }
+
+    @Test
+    public void deserializeReturnNull() throws Exception {
+        final String json = "{\"color\":{\"red\":2550,\"green\":0,\"blue\":0}}";
+
+        final JsonbConfig config = new JsonbConfig();
+        config.setProperty("johnzon.snippetMaxLength", 20);
+
+        final WidgetWithReturnNullDeserializer widget = ((Callable<WidgetWithReturnNullDeserializer>) () -> {
+            try (final Jsonb jsonb = JsonbBuilder.create(config)) {
+                return jsonb.fromJson(json, WidgetWithReturnNullDeserializer.class);
+            }
+        }).call();
+
+        assertNotNull(widget);
+        assertNull(widget.getColor());
+    }
+
+
+    public static class FailedSerializer implements JsonbSerializer<Color>, JsonbDeserializer<Color> {
+        @Override
+        public Color deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext, final Type type) {
+            throw DESERIALIZE_EXCEPTION;
+        }
+
+        @Override
+        public void serialize(final Color color, final JsonGenerator jsonGenerator, final SerializationContext serializationContext) {
+            throw SERIALIZE_EXCEPTION;
+        }
+    }
+
+    public static class FailedConstructorSerializer implements JsonbSerializer<Color>, JsonbDeserializer<Color> {
+        public FailedConstructorSerializer() throws Exception {
+            throw CONSTRUCTOR_EXCEPTION;
+        }
+
+        @Override
+        public Color deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext, final Type type) {
+            return null;
+        }
+
+        @Override
+        public void serialize(final Color color, final JsonGenerator jsonGenerator, final SerializationContext serializationContext) {
+
+        }
+    }
+
+    public static class ReturnNullDeserializer implements JsonbDeserializer<Color> {
+        @Override
+        public Color deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext, final Type type) {
+            return null;
+        }
+    }
+
+    public static class WidgetWithReturnNullDeserializer {
+        @JsonbTypeDeserializer(ReturnNullDeserializer.class)
+        private Color color;
+
+        public WidgetWithReturnNullDeserializer() {
+        }
+
+        public WidgetWithReturnNullDeserializer(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class WidgetWithFailedConstructorSerializer {
+        @JsonbTypeDeserializer(FailedConstructorSerializer.class)
+        @JsonbTypeSerializer(FailedConstructorSerializer.class)
+        private Color color;
+
+        public WidgetWithFailedConstructorSerializer() {
+        }
+
+        public WidgetWithFailedConstructorSerializer(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class WidgetWithFailedSerializer {
+        @JsonbTypeDeserializer(FailedSerializer.class)
+        @JsonbTypeSerializer(FailedSerializer.class)
+        private Color color;
+
+        public WidgetWithFailedSerializer() {
+        }
+
+        public WidgetWithFailedSerializer(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class Color {
+        private final String name;
+
+        public Color(final String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+}
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SnippetMaxLengthTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SnippetMaxLengthTest.java
index 9edb94f..93c437e 100644
--- a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SnippetMaxLengthTest.java
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SnippetMaxLengthTest.java
@@ -38,7 +38,9 @@
             jsonb.fromJson(s, Person.class);
             fail();
         } catch (JsonbException e) {
-            assertEquals("Can't map JSON Object to class java.lang.String: {\"first\":\"Charlie\",\"last\":\"Brown\"}", e.getMessage());
+            assertMessage("Person property 'name' of type String cannot be mapped to json object value: " +
+                    "{\"first\":\"Charlie\",\"last\":\"Brown\"}\n" +
+                    "Unable to map json object value to class java.lang.String: {\"first\":\"Charlie\",\"last\":\"Brown\"}", e.getMessage());
         }
     }
 
@@ -49,8 +51,9 @@
             jsonb.fromJson(s, Person.class);
             fail();
         } catch (JsonbException e) {
-            assertEquals("Can't map JSON Object to class java.lang.String: " +
-                    "{\"first\":\"Charlie\",\"last\":\"Brown\",\"age\":\"8.5\",\"dog...", e.getMessage());
+            assertMessage("Person property 'name' of type String cannot be mapped to json object value:" +
+                    " {\"first\":\"Charlie\",\"last\":\"Brown\",\"age\":\"8.5\",\"dog...\n" +
+                    "Unable to map json object value to class java.lang.String: {\"first\":\"Charlie\",\"last\":\"Brown\",\"age\":\"8.5\",\"dog...", e.getMessage());
         }
     }
 
@@ -63,10 +66,19 @@
             jsonb.fromJson(s, Person.class);
             fail();
         } catch (JsonbException e) {
-            assertEquals("Can't map JSON Object to class java.lang.String: {\"first\":\"Charlie\",\"...", e.getMessage());
+            assertMessage("Person property 'name' of type String cannot be mapped to json object value:" +
+                    " {\"first\":\"Charlie\",\"...\n" +
+                    "Unable to map json object value to class java.lang.String: {\"first\":\"Charlie\",\"...", e.getMessage());
         }
     }
 
+    private void assertMessage(final String expected, final String actual) {
+        assertEquals(normalize(expected), normalize(actual));
+    }
+
+    private String normalize(final String message) {
+        return message.replace("\r\n", "\n");
+    }
 
     @Test
     public void testSetAsString() throws Exception {
@@ -77,7 +89,9 @@
             jsonb.fromJson(s, Person.class);
             fail();
         } catch (JsonbException e) {
-            assertEquals("Can't map JSON Object to class java.lang.String: {\"first\":\"Charlie\",\"...", e.getMessage());
+            assertMessage("Person property 'name' of type String cannot be mapped to json object value:" +
+                    " {\"first\":\"Charlie\",\"...\n" +
+                    "Unable to map json object value to class java.lang.String: {\"first\":\"Charlie\",\"...", e.getMessage());
         }
     }
 
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ExceptionMessages.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ExceptionMessages.java
new file mode 100644
index 0000000..58825c0
--- /dev/null
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/ExceptionMessages.java
@@ -0,0 +1,108 @@
+/*
+ * 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.johnzon.mapper;
+
+import javax.json.JsonValue;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+
+import static javax.json.JsonValue.ValueType.ARRAY;
+import static javax.json.JsonValue.ValueType.FALSE;
+import static javax.json.JsonValue.ValueType.NUMBER;
+import static javax.json.JsonValue.ValueType.OBJECT;
+import static javax.json.JsonValue.ValueType.STRING;
+import static javax.json.JsonValue.ValueType.TRUE;
+
+public final class ExceptionMessages {
+
+    private ExceptionMessages() {
+    }
+
+    public static String simpleName(final Type type) {
+        if (type instanceof Class) {
+            final Class<?> clazz = (Class<?>) type;
+            return clazz.getSimpleName();
+        }
+        
+        if (type instanceof ParameterizedType) {
+            final ParameterizedType parameterizedType = (ParameterizedType) type;
+            return simpleName(parameterizedType.getRawType()) +
+                    "<" +
+                    join(",", parameterizedType.getActualTypeArguments()) +
+                    ">";
+        }
+        
+        if (type instanceof GenericArrayType) {
+            final GenericArrayType genericArrayType = (GenericArrayType) type;
+            return simpleName(genericArrayType.getGenericComponentType()) + "[]";
+        }
+
+        if (type instanceof WildcardType) {
+            final WildcardType wildcardType = (WildcardType) type;
+
+            if (wildcardType.getLowerBounds().length > 0) {
+                return "? super " + join(" & ", wildcardType.getLowerBounds());
+            }
+
+            if (wildcardType.getUpperBounds().length > 0) {
+                return "? extends " + join(" & ", wildcardType.getUpperBounds());
+            }
+
+            // This should never happen, but it's always safe to fallback on getTypeName()
+            // so we do that instead of throwing an exception
+            return wildcardType.getTypeName();
+        }
+
+        // Some Type derivative we've never seen.  Fallback on getTypeName()
+        return type.getTypeName();
+    }
+
+    public static String description(final JsonValue value) {
+        return description(value == null ? null : value.getValueType());
+    }
+
+    public static String description(final JsonValue.ValueType type) {
+        if (type == OBJECT || type == ARRAY || type == STRING) {
+            return "json " + type.toString().toLowerCase() + " value";
+        }
+        if (type == NUMBER) {
+            return "json numeric value";
+        }
+        if (type == TRUE || type == FALSE) {
+            return "json boolean value";
+        }
+
+        return "json value";
+    }
+
+    private static String join(final String delimiter, final Type[] args) {
+        if (args.length == 0) {
+            return "";
+        }
+
+        final StringBuilder sb = new StringBuilder(simpleName(args[0]));
+
+        for (int i = 1; i < args.length; i++) {
+            sb.append(delimiter);
+            sb.append(simpleName(args[i]));
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/FactoryCreateException.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/FactoryCreateException.java
new file mode 100644
index 0000000..1b8fc3d
--- /dev/null
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/FactoryCreateException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.johnzon.mapper;
+
+import javax.json.JsonObject;
+import java.lang.reflect.Type;
+
+public class FactoryCreateException extends MapperException {
+    public FactoryCreateException(final Type type, final JsonObject object, final String snippet, final Exception e) {
+        super(String.format("%s cannot be constructed to deserialize %s: %s%n%s",
+                ExceptionMessages.simpleName(type), ExceptionMessages.description(object),
+                snippet, e.getMessage()
+        ), e);
+    }
+}
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
index 546f131..f98edb6 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
@@ -242,7 +242,9 @@
             return (T) Boolean.FALSE;
         }
 
-        throw new IllegalArgumentException("Unsupported " + jsonValue + " for type " + targetType);
+        final String snippet = config.getSnippet().of(jsonValue);
+        final String description = ExceptionMessages.description(valueType);
+        throw new IllegalArgumentException(targetType + " does not support " + description + ": " + snippet);
     }
 
     private boolean isDedup() {
@@ -344,7 +346,9 @@
             }
         }
         if (classMapping == null) {
-            throw new MapperException("Can't map JSON Object to " + type + ": " + config.getSnippet().of(object));
+            final String snippet = config.getSnippet().of(object);
+            final String description = ExceptionMessages.description(object);
+            throw new MapperException("Unable to map " + description + " to " + type + ": " + snippet);
         }
 
         if (applyObjectConverter && classMapping.reader != null && (skippedConverters == null || !skippedConverters.contains(type))) {
@@ -361,7 +365,7 @@
         */
 
         if (classMapping.factory == null) {
-            throw new MapperException(classMapping.clazz + " not instantiable");
+            throw new MissingFactoryException(classMapping.clazz, object, config.getSnippet().of(object));
         }
 
         if (config.isFailOnUnknown()) {
@@ -373,11 +377,19 @@
         }
 
         Object t;
-        if (classMapping.factory.getParameterTypes() == null || classMapping.factory.getParameterTypes().length == 0) {
-            t = classMapping.factory.create(null);
-        } else {
-            t = classMapping.factory.create(createParameters(classMapping, object, jsonPointer));
+        try {
+            if (classMapping.factory.getParameterTypes() == null || classMapping.factory.getParameterTypes().length == 0) {
+                t = classMapping.factory.create(null);
+            } else {
+                t = classMapping.factory.create(createParameters(classMapping, object, jsonPointer));
+            }
+        } catch (FactoryCreateException e){
+            throw e;
+        } catch (Exception e) {
+            final String snippet = config.getSnippet().of(object);
+            throw new FactoryCreateException(type, object, snippet, e);
         }
+
         // store the new object under it's jsonPointer in case it gets referenced later
         if (jsonPointers == null) {
             if (classMapping.deduplicateObjects || config.isDeduplicateObjects()) {
@@ -399,36 +411,43 @@
             final JsonValue jsonValue = jsonEntry.getValue();
             final JsonValue.ValueType valueType = jsonValue != null ? jsonValue.getValueType() : null;
 
-            if (JsonValue.class == value.paramType) {
-                value.writer.write(t, jsonValue);
-                continue;
-            }
-            if (jsonValue == null) {
-                continue;
-            }
+            try {
+                if (JsonValue.class == value.paramType) {
+                    value.writer.write(t, jsonValue);
+                    continue;
+                }
+                if (jsonValue == null) {
+                    continue;
+                }
 
-            final AccessMode.Writer setterMethod = value.writer;
-            if (NULL == valueType) { // forced
-                setterMethod.write(t, null);
-            } else {
-                Object existingInstance = null;
-                if (config.isReadAttributeBeforeWrite()) {
-                    final Mappings.Getter getter = classMapping.getters.get(jsonEntry.getKey());
-                    if (getter != null) {
-                        try {
-                            existingInstance = getter.reader.read(t);
-                        } catch (final RuntimeException re) {
-                            // backward compatibility
+                final AccessMode.Writer setterMethod = value.writer;
+                if (NULL == valueType) { // forced
+                    setterMethod.write(t, null);
+                } else {
+                    Object existingInstance = null;
+                    if (config.isReadAttributeBeforeWrite()) {
+                        final Mappings.Getter getter = classMapping.getters.get(jsonEntry.getKey());
+                        if (getter != null) {
+                            try {
+                                existingInstance = getter.reader.read(t);
+                            } catch (final RuntimeException re) {
+                                // backward compatibility
+                            }
                         }
                     }
+                    final Object convertedValue = toValue(
+                            existingInstance, jsonValue, value.converter, value.itemConverter,
+                            value.paramType, value.objectConverter,
+                            isDedup() ? new JsonPointerTracker(jsonPointer, jsonEntry.getKey()) : null, inType);
+                    if (convertedValue != null) {
+                        setterMethod.write(t, convertedValue);
+                    }
                 }
-                final Object convertedValue = toValue(
-                        existingInstance, jsonValue, value.converter, value.itemConverter,
-                        value.paramType, value.objectConverter,
-                        isDedup() ? new JsonPointerTracker(jsonPointer, jsonEntry.getKey()) : null, inType);
-                if (convertedValue != null) {
-                    setterMethod.write(t, convertedValue);
-                }
+            } catch (SetterMappingException alreadyHandled) {
+                throw alreadyHandled;
+            } catch (Exception e) {
+                final String snippet = jsonValue == null? "null": config.getSnippet().of(jsonValue);
+                throw new SetterMappingException(classMapping.clazz, jsonEntry.getKey(), value.writer.getType(), valueType, snippet, e);
             }
         }
         if (classMapping.anySetter != null) {
@@ -622,7 +641,9 @@
             if (JsonValue.ValueType.FALSE == valueType) {
                 return false;
             }
-            throw new MapperException("Unable to parse " + jsonValue + " to boolean");
+            final String snippet = config.getSnippet().of(jsonValue);
+            final String description = ExceptionMessages.description(valueType);
+            throw new MapperException("Unable to parse " + description + " to boolean: " + snippet);
         }
 
         if (config.isTreatByteArrayAsBase64() && jsonValue.getValueType() == JsonValue.ValueType.STRING && (type == byte[].class /*|| type == Byte[].class*/)) {
@@ -732,7 +753,9 @@
             return itemConverter.to(string);
         }
 
-        throw new MapperException("Unable to parse " + jsonValue + " to " + type);
+        final String snippet = config.getSnippet().of(jsonValue);
+        final String description = ExceptionMessages.description(valueType);
+        throw new MapperException("Unable to parse " + description + " to " + type + ": " + snippet);
     }
 
     private Object buildArray(final Type type, final JsonArray jsonArray, final Adapter itemConverter,
@@ -805,8 +828,12 @@
             boolean[] array = new boolean[jsonArray.size()];
             int i = 0;
             for (final JsonValue value : jsonArray) {
-                array[i] = (boolean) toObject(null, value, componentType, itemConverter,
+                final Object object = toObject(null, value, componentType, itemConverter,
                         isDedup() ? new JsonPointerTracker(jsonPointer, i) : null, rootType);
+                if (object == null) {
+                    throw new IllegalStateException("json array mapped to boolean[] has null value at index " + i);
+                }
+                array[i] = (boolean) object;
                 i++;
             }
             return array;
@@ -815,8 +842,12 @@
             byte[] array = new byte[jsonArray.size()];
             int i = 0;
             for (final JsonValue value : jsonArray) {
-                array[i] = (byte) toObject(null, value, componentType, itemConverter,
+                final Object object = toObject(null, value, componentType, itemConverter,
                         isDedup() ? new JsonPointerTracker(jsonPointer, i) : null, rootType);
+                if (object == null) {
+                    throw new IllegalStateException("json array mapped to byte[] has null value at index " + i);
+                }
+                array[i] = (byte) object;
                 i++;
             }
             return array;
@@ -825,8 +856,12 @@
             char[] array = new char[jsonArray.size()];
             int i = 0;
             for (final JsonValue value : jsonArray) {
-                array[i] = (char) toObject(null, value, componentType, itemConverter,
+                final Object object = toObject(null, value, componentType, itemConverter,
                         isDedup() ? new JsonPointerTracker(jsonPointer, i) : null, rootType);
+                if (object == null) {
+                    throw new IllegalStateException("json array mapped to char[] has null value at index " + i);
+                }
+                array[i] = (char) object;
                 i++;
             }
             return array;
@@ -835,8 +870,12 @@
             short[] array = new short[jsonArray.size()];
             int i = 0;
             for (final JsonValue value : jsonArray) {
-                array[i] = (short) toObject(null, value, componentType, itemConverter,
+                final Object object = toObject(null, value, componentType, itemConverter,
                         isDedup() ? new JsonPointerTracker(jsonPointer, i) : null, rootType);
+                if (object == null) {
+                    throw new IllegalStateException("json array mapped to short[] has null value at index " + i);
+                }
+                array[i] = (short) object;
                 i++;
             }
             return array;
@@ -845,8 +884,12 @@
             int[] array = new int[jsonArray.size()];
             int i = 0;
             for (final JsonValue value : jsonArray) {
-                array[i] = (int) toObject(null, value, componentType, itemConverter,
+                final Object object = toObject(null, value, componentType, itemConverter,
                         isDedup() ? new JsonPointerTracker(jsonPointer, i) : null, rootType);
+                if (object == null) {
+                    throw new IllegalStateException("json array mapped to int[] has null value at index " + i);
+                }
+                array[i] = (int) object;
                 i++;
             }
             return array;
@@ -855,8 +898,12 @@
             long[] array = new long[jsonArray.size()];
             int i = 0;
             for (final JsonValue value : jsonArray) {
-                array[i] = (long) toObject(null, value, componentType, itemConverter,
+                final Object object = toObject(null, value, componentType, itemConverter,
                         isDedup() ? new JsonPointerTracker(jsonPointer, i) : null, rootType);
+                if (object == null) {
+                    throw new IllegalStateException("json array mapped to long[] has null value at index " + i);
+                }
+                array[i] = (long) object;
                 i++;
             }
             return array;
@@ -865,8 +912,12 @@
             float[] array = new float[jsonArray.size()];
             int i = 0;
             for (final JsonValue value : jsonArray) {
-                array[i] = (float) toObject(null, value, componentType, itemConverter,
+                final Object object = toObject(null, value, componentType, itemConverter,
                         isDedup() ? new JsonPointerTracker(jsonPointer, i) : null, rootType);
+                if (object == null) {
+                    throw new IllegalStateException("json array mapped to float[] has null value at index " + i);
+                }
+                array[i] = (float) object;
                 i++;
             }
             return array;
@@ -875,8 +926,12 @@
             double[] array = new double[jsonArray.size()];
             int i = 0;
             for (final JsonValue value : jsonArray) {
-                array[i] = (double) toObject(null, value, componentType, itemConverter,
+                final Object object = toObject(null, value, componentType, itemConverter,
                         isDedup() ? new JsonPointerTracker(jsonPointer, i) : null, rootType);
+                if (object == null) {
+                    throw new IllegalStateException("json array mapped to double[] has null value at index " + i);
+                }
+                array[i] = (double) object;
                 i++;
             }
             return array;
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MissingFactoryException.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MissingFactoryException.java
new file mode 100644
index 0000000..0f1ccc8
--- /dev/null
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MissingFactoryException.java
@@ -0,0 +1,65 @@
+/*
+ * 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.johnzon.mapper;
+
+import javax.json.JsonObject;
+import java.lang.reflect.Constructor;
+import java.util.stream.Stream;
+
+
+public class MissingFactoryException extends MapperException {
+    public MissingFactoryException(final Class<?> clazz, final JsonObject object, final String json) {
+        super(message(clazz, object, json));
+    }
+
+    private static String message(final Class<?> clazz, final JsonObject object, final String json) {
+        if (clazz.isArray()) {
+            return String.format("%s array not a suitable datatype for %s: %s",
+                    clazz.getSimpleName(),
+                    ExceptionMessages.description(object),
+                    json);
+        }
+
+        if (clazz.isInterface()) {
+            return String.format("%s is an interface and requires an adapter or factory.  Cannot deserialize %s: %s%n%s not instantiable",
+                    clazz.getSimpleName(),
+                    ExceptionMessages.description(object),
+                    json,
+                    clazz);
+        }
+
+        String message = String.format("%s has no suitable constructor or factory.  Cannot deserialize %s: %s",
+                clazz.getSimpleName(),
+                ExceptionMessages.description(object),
+                json);
+
+        final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
+        final long constructorsWithParameters = Stream.of(constructors)
+                .filter(constructor -> constructor.getParameterTypes().length > 0)
+                .count();
+
+        // Was a constructor with parameters our only option?  If so, help people
+        // learn how to properly use constructors with parameters
+        if (constructorsWithParameters > 0 && constructors.length == constructorsWithParameters) {
+            message += "\nUse Johnzon @ConstructorProperties or @JsonbCreator if constructor arguments are needed";
+        }
+
+        // Add full class name as final detail
+        message += "\n" + clazz + " not instantiable";
+        return message;
+    }
+}
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/SetterMappingException.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/SetterMappingException.java
new file mode 100644
index 0000000..e1bf059
--- /dev/null
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/SetterMappingException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.johnzon.mapper;
+
+import javax.json.JsonValue;
+import java.lang.reflect.Type;
+
+public class SetterMappingException extends MapperException {
+
+    public SetterMappingException(final Class<?> clazz, final String entryName, final Type type,
+                                  final JsonValue.ValueType valueType, final String jsonValue, final Exception cause) {
+        super(message(clazz, entryName, type, valueType, jsonValue, cause), cause);
+    }
+
+    private static String message(final Class<?> clazz, final String entryName, final Type type,
+                                  final JsonValue.ValueType valueType, final String jsonValue, final Exception cause) {
+
+        return String.format("%s property '%s' of type %s cannot be mapped to %s: %s%n%s",
+                clazz.getSimpleName(),
+                entryName,
+                ExceptionMessages.simpleName(type),
+                ExceptionMessages.description(valueType),
+                jsonValue,
+                cause.getMessage()
+        );
+    }
+
+}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/DeserializationExceptionMessagesTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/DeserializationExceptionMessagesTest.java
new file mode 100644
index 0000000..ac6fec9
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/DeserializationExceptionMessagesTest.java
@@ -0,0 +1,1539 @@
+/*
+ * 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.johnzon.mapper;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class DeserializationExceptionMessagesTest {
+
+
+    @Test
+    public void objectFromString() throws Exception {
+        assertMessage("{ \"object\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'object' of type Color cannot be mapped to json string value: \"Supercalifragilisti.." +
+                        ".\nMissing a Converter for type class org.apache.johnzon.mapper.DeserializationExceptionMessagesTest$C" +
+                        "olor to convert the JSON String 'Supercalifragilisticexpialidocious' . Please register a custom conv" +
+                        "erter for it.");
+    }
+
+    @Test
+    public void objectFromNumber() throws Exception {
+        assertMessage("{ \"object\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'object' of type Color cannot be mapped to json numeric value: 122333444455555.6666." +
+                        "..\nUnable to parse json numeric value to class org.apache.johnzon.mapper.DeserializationExceptionMess" +
+                        "agesTest$Color: 122333444455555.6666...");
+    }
+
+    @Test
+    public void objectFromBoolean() throws Exception {
+        assertMessage("{ \"object\" : true }",
+                "Widget property 'object' of type Color cannot be mapped to json boolean value: true\nUnable to parse " +
+                        "json boolean value to class org.apache.johnzon.mapper.DeserializationExceptionMessagesTest$Color: tru" +
+                        "e");
+    }
+
+    @Test
+    public void objectFromArrayOfObject() throws Exception {
+        assertMessage("{ \"object\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'object' of type Color cannot be mapped to json array value: [{\"red\":255,\"green\":..." +
+                        "\ntype class org.apache.johnzon.mapper.DeserializationExceptionMessagesTest$Color not supported");
+    }
+
+    @Test
+    public void objectFromArrayOfString() throws Exception {
+        assertMessage("{ \"object\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'object' of type Color cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"..." +
+                        "\ntype class org.apache.johnzon.mapper.DeserializationExceptionMessagesTest$Color not supported");
+    }
+
+    @Test
+    public void objectFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"object\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'object' of type Color cannot be mapped to json array value: [2,3,5,7,11,13,17,19..." +
+                        "\ntype class org.apache.johnzon.mapper.DeserializationExceptionMessagesTest$Color not supported");
+    }
+
+    @Test
+    public void objectFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"object\" : [true,false,true,true,false] }",
+                "Widget property 'object' of type Color cannot be mapped to json array value: [true,false,true,tru..." +
+                        "\ntype class org.apache.johnzon.mapper.DeserializationExceptionMessagesTest$Color not supported");
+    }
+
+    @Test
+    public void stringFromArrayOfObject() throws Exception {
+        assertMessage("{ \"string\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'string' of type String cannot be mapped to json array value: [{\"red\":255,\"green\":...\n" +
+                        "type class java.lang.String not supported");
+    }
+
+    @Test
+    public void stringFromArrayOfString() throws Exception {
+        assertMessage("{ \"string\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'string' of type String cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"...\n" +
+                        "type class java.lang.String not supported");
+    }
+
+    @Test
+    public void stringFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"string\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'string' of type String cannot be mapped to json array value: [2,3,5,7,11,13,17,19...\n" +
+                        "type class java.lang.String not supported");
+    }
+
+    @Test
+    public void stringFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"string\" : [true,false,true,true,false] }",
+                "Widget property 'string' of type String cannot be mapped to json array value: [true,false,true,tru...\n" +
+                        "type class java.lang.String not supported");
+    }
+
+    @Test
+    public void numberFromObject() throws Exception {
+        assertMessage("{ \"number\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'number' of type Integer cannot be mapped to json object value: {\"red\":255,\"green\":1" +
+                        "...\nUnable to map json object value to class java.lang.Integer: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void numberFromString() throws Exception {
+        assertMessage("{ \"number\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'number' of type Integer cannot be mapped to json string value: \"Supercalifragilisti" +
+                        "...\nFor input string: \"Supercalifragilisticexpialidocious\"");
+    }
+
+    @Test
+    public void numberFromBoolean() throws Exception {
+        assertMessage("{ \"number\" : true }",
+                "Widget property 'number' of type Integer cannot be mapped to json boolean value: true\nUnable to pars" +
+                        "e json boolean value to class java.lang.Integer: true");
+    }
+
+    @Test
+    public void numberFromArrayOfObject() throws Exception {
+        assertMessage("{ \"number\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'number' of type Integer cannot be mapped to json array value: [{\"red\":255,\"green\":." +
+                        "..\ntype class java.lang.Integer not supported");
+    }
+
+    @Test
+    public void numberFromArrayOfString() throws Exception {
+        assertMessage("{ \"number\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'number' of type Integer cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"." +
+                        "..\ntype class java.lang.Integer not supported");
+    }
+
+    @Test
+    public void numberFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"number\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'number' of type Integer cannot be mapped to json array value: [2,3,5,7,11,13,17,19." +
+                        "..\ntype class java.lang.Integer not supported");
+    }
+
+    @Test
+    public void numberFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"number\" : [true,false,true,true,false] }",
+                "Widget property 'number' of type Integer cannot be mapped to json array value: [true,false,true,tru." +
+                        "..\ntype class java.lang.Integer not supported");
+    }
+
+    @Test
+    public void intPrimitiveFromObject() throws Exception {
+        assertMessage("{ \"intPrimitive\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json object value: {\"red\":255,\"green\"" +
+                        ":1...\nUnable to map json object value to int: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void intPrimitiveFromString() throws Exception {
+        assertMessage("{ \"intPrimitive\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json string value: \"Supercalifragilis" +
+                        "ti...\nMissing a Converter for type int to convert the JSON String 'Supercalifragilisticexpialidociou" +
+                        "s' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void intPrimitiveFromNumber() throws Exception {
+        assertMessage("{ \"intPrimitive\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json numeric value: 122333444455555.6" +
+                        "666...\nNot an int/long, use other value readers");
+    }
+
+    @Test
+    public void intPrimitiveFromBoolean() throws Exception {
+        assertMessage("{ \"intPrimitive\" : true }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json boolean value: true\nUnable to pa" +
+                        "rse json boolean value to int: true");
+    }
+
+    @Test
+    public void intPrimitiveFromNull() throws Exception {
+        assertMessage("{ \"intPrimitive\" : null }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json value: null\nError calling public" +
+                        " void org.apache.johnzon.mapper.DeserializationExceptionMessagesTest$Widget.setIntPrimitive(int)");
+    }
+
+    @Test
+    public void intPrimitiveFromArrayOfObject() throws Exception {
+        assertMessage("{ \"intPrimitive\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json array value: [{\"red\":255,\"green\"" +
+                        ":...\ntype int not supported");
+    }
+
+    @Test
+    public void intPrimitiveFromArrayOfString() throws Exception {
+        assertMessage("{ \"intPrimitive\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json array value: [\"Klaatu\",\"barada\"," +
+                        "\"...\ntype int not supported");
+    }
+
+    @Test
+    public void intPrimitiveFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"intPrimitive\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json array value: [2,3,5,7,11,13,17,1" +
+                        "9...\ntype int not supported");
+    }
+
+    @Test
+    public void intPrimitiveFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"intPrimitive\" : [true,false,true,true,false] }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json array value: [true,false,true,tr" +
+                        "u...\ntype int not supported");
+    }
+
+    @Test
+    public void booleanFromObject() throws Exception {
+        assertMessage("{ \"bool\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json object value: {\"red\":255,\"green\":1.." +
+                        ".\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void booleanFromString() throws Exception {
+        assertMessage("{ \"bool\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json string value: \"Supercalifragilisti.." +
+                        ".\nUnable to parse json string value to boolean: \"Supercalifragilisti...");
+    }
+
+    @Test
+    public void booleanFromNumber() throws Exception {
+        assertMessage("{ \"bool\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json numeric value: 122333444455555.6666." +
+                        "..\nUnable to parse json numeric value to boolean: 122333444455555.6666...");
+    }
+
+    @Test
+    public void booleanFromArrayOfObject() throws Exception {
+        assertMessage("{ \"bool\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json array value: [{\"red\":255,\"green\":..." +
+                        "\nUnable to parse json array value to boolean: [{\"red\":255,\"green\":...");
+    }
+
+    @Test
+    public void booleanFromArrayOfString() throws Exception {
+        assertMessage("{ \"bool\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"..." +
+                        "\nUnable to parse json array value to boolean: [\"Klaatu\",\"barada\",\"...");
+    }
+
+    @Test
+    public void booleanFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"bool\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json array value: [2,3,5,7,11,13,17,19..." +
+                        "\nUnable to parse json array value to boolean: [2,3,5,7,11,13,17,19...");
+    }
+
+    @Test
+    public void booleanFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"bool\" : [true,false,true,true,false] }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json array value: [true,false,true,tru..." +
+                        "\nUnable to parse json array value to boolean: [true,false,true,tru...");
+    }
+
+    @Test
+    public void boolPrimitiveFromObject() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json object value: {\"red\":255,\"g" +
+                        "reen\":1...\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void boolPrimitiveFromString() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json string value: \"Supercalifra" +
+                        "gilisti...\nUnable to parse json string value to boolean: \"Supercalifragilisti...");
+    }
+
+    @Test
+    public void boolPrimitiveFromNumber() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json numeric value: 122333444455" +
+                        "555.6666...\nUnable to parse json numeric value to boolean: 122333444455555.6666...");
+    }
+
+    @Test
+    public void boolPrimitiveFromNull() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : null }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json value: null\nError calling p" +
+                        "ublic void org.apache.johnzon.mapper.DeserializationExceptionMessagesTest$Widget.setBoolPrimitive(boo" +
+                        "lean)");
+    }
+
+    @Test
+    public void boolPrimitiveFromArrayOfObject() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json array value: [{\"red\":255,\"g" +
+                        "reen\":...\nUnable to parse json array value to boolean: [{\"red\":255,\"green\":...");
+    }
+
+    @Test
+    public void boolPrimitiveFromArrayOfString() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json array value: [\"Klaatu\",\"bar" +
+                        "ada\",\"...\nUnable to parse json array value to boolean: [\"Klaatu\",\"barada\",\"...");
+    }
+
+    @Test
+    public void boolPrimitiveFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json array value: [2,3,5,7,11,13" +
+                        ",17,19...\nUnable to parse json array value to boolean: [2,3,5,7,11,13,17,19...");
+    }
+
+    @Test
+    public void boolPrimitiveFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"boolPrimitive\" : [true,false,true,true,false] }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json array value: [true,false,tr" +
+                        "ue,tru...\nUnable to parse json array value to boolean: [true,false,true,tru...");
+    }
+
+    @Test
+    public void enumFromObject() throws Exception {
+        assertMessage("{ \"unit\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json object value: {\"red\":255,\"green\":1." +
+                        "..\nUnable to map json object value to class java.lang.String: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void enumFromString() throws Exception {
+        assertMessage("{ \"unit\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json string value: \"Supercalifragilisti...\n" +
+                        "Illegal class java.util.concurrent.TimeUnit enum value: Supercalifragilisticexpialidocious");
+    }
+
+    @Test
+    public void enumFromNumber() throws Exception {
+        assertMessage("{ \"unit\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json numeric value: 122333444455555.6666...\n" +
+                        "Illegal class java.util.concurrent.TimeUnit enum value: 122333444455555.666666777777788888888");
+    }
+
+    @Test
+    public void enumFromBoolean() throws Exception {
+        assertMessage("{ \"unit\" : true }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json boolean value: true\n" +
+                        "Illegal class java.util.concurrent.TimeUnit enum value: true");
+    }
+
+    @Test
+    public void enumFromArrayOfObject() throws Exception {
+        assertMessage("{ \"unit\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json array value: [{\"red\":255,\"green\":.." +
+                        ".\nclass java.lang.String does not support json array value: [{\"red\":255,\"green\":...");
+    }
+
+    @Test
+    public void enumFromArrayOfString() throws Exception {
+        assertMessage("{ \"unit\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json array value: [\"Klaatu\",\"barada\",\".." +
+                        ".\nclass java.lang.String does not support json array value: [\"Klaatu\",\"barada\",\"...");
+    }
+
+    @Test
+    public void enumFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"unit\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json array value: [2,3,5,7,11,13,17,19.." +
+                        ".\nclass java.lang.String does not support json array value: [2,3,5,7,11,13,17,19...");
+    }
+
+    @Test
+    public void enumFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"unit\" : [true,false,true,true,false] }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json array value: [true,false,true,tru.." +
+                        ".\nclass java.lang.String does not support json array value: [true,false,true,tru...");
+    }
+
+    @Test
+    @Ignore("this probably should not pass")
+    public void dateFromObject() throws Exception {
+        assertMessage("{ \"date\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'date' of type Date cannot be mapped to json object value: {\"red\":255,\"green\":1...\nU" +
+                        "nable to map json object value to class java.lang.String: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void dateFromString() throws Exception {
+        assertMessage("{ \"date\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'date' of type Date cannot be mapped to json string value: \"Supercalifragilisti...\n" +
+                        "java.text.ParseException: Unparseable date: \"Supercalifragilisticexpialidocious\"");
+    }
+
+    @Test
+    public void dateFromNumber() throws Exception {
+        assertMessage("{ \"date\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'date' of type Date cannot be mapped to json numeric value: 122333444455555.6666...\n" +
+                        "Unable to parse json numeric value to class java.util.Date: 122333444455555.6666...");
+    }
+
+    @Test
+    public void dateFromBoolean() throws Exception {
+        assertMessage("{ \"date\" : true }",
+                "Widget property 'date' of type Date cannot be mapped to json boolean value: true\n" +
+                        "Unable to parse json boolean value to class java.util.Date: true");
+    }
+
+    @Test
+    public void dateFromArrayOfObject() throws Exception {
+        assertMessage("{ \"date\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'date' of type Date cannot be mapped to json array value: [{\"red\":255,\"green\":...\n" +
+                        "type class java.util.Date not supported");
+    }
+
+    @Test
+    public void dateFromArrayOfString() throws Exception {
+        assertMessage("{ \"date\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'date' of type Date cannot be mapped to json array value: [\"Klaatu\",\"barada\",\"...\n" +
+                        "type class java.util.Date not supported");
+    }
+
+    @Test
+    public void dateFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"date\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'date' of type Date cannot be mapped to json array value: [2,3,5,7,11,13,17,19...\n" +
+                        "type class java.util.Date not supported");
+    }
+
+    @Test
+    public void dateFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"date\" : [true,false,true,true,false] }",
+                "Widget property 'date' of type Date cannot be mapped to json array value: [true,false,true,tru...\n" +
+                        "type class java.util.Date not supported");
+    }
+
+    @Test
+    public void arrayOfObjectFromObject() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json object value: {\"red\":255," +
+                        "\"green\":1...\nColor[] array not a suitable datatype for json object value: {\"red" +
+                        "\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfObjectFromString() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json string value: \"Supercalifra" +
+                        "gilisti...\nMissing a Converter for type class [Lorg.apache.johnzon.mapper.DeserializationExceptionMes" +
+                        "sagesTest$Color; to convert the JSON String 'Supercalifragilisticexpialidocious' . Please register a" +
+                        " custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfObjectFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json numeric value: 122333444455" +
+                        "555.6666...\nUnable to parse json numeric value to class [Lorg.apache.johnzon.mapper.DeserializationEx" +
+                        "ceptionMessagesTest$Color;: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfObjectFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : true }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json boolean value: true\nUnable " +
+                        "to parse json boolean value to class [Lorg.apache.johnzon.mapper.DeserializationExceptionMessagesTest" +
+                        "$Color;: true");
+    }
+
+    @Test
+    public void arrayOfObjectFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json array value: [\"Klaatu\",\"bar" +
+                        "ada\",\"...\nMissing a Converter for type class org.apache.johnzon.mapper.DeserializationExceptionMessag" +
+                        "esTest$Color to convert the JSON String 'Klaatu' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfObjectFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json array value: [2,3,5,7,11,13" +
+                        ",17,19...\nUnable to parse json numeric value to class org.apache.johnzon.mapper.DeserializationExcept" +
+                        "ionMessagesTest$Color: 2");
+    }
+
+    @Test
+    public void arrayOfObjectFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfObject\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json array value: [true,false,tr" +
+                        "ue,tru...\nUnable to parse json boolean value to class org.apache.johnzon.mapper.DeserializationExcept" +
+                        "ionMessagesTest$Color: true");
+    }
+
+    @Test
+    public void arrayOfStringFromObject() throws Exception {
+        assertMessage("{ \"arrayOfString\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json object value: {\"red\":255,\"" +
+                        "green\":1...\nString[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfStringFromString() throws Exception {
+        assertMessage("{ \"arrayOfString\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json string value: \"Supercalifr" +
+                        "agilisti...\nMissing a Converter for type class [Ljava.lang.String; to convert the JSON String 'Super" +
+                        "califragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfStringFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfString\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json numeric value: 12233344445" +
+                        "5555.6666...\nUnable to parse json numeric value to class [Ljava.lang.String;: 122333444455555.6666.." +
+                        ".");
+    }
+
+    @Test
+    public void arrayOfStringFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfString\" : true }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json boolean value: true\nUnable" +
+                        " to parse json boolean value to class [Ljava.lang.String;: true");
+    }
+
+    @Test
+    public void arrayOfStringFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfString\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json array value: [{\"red\":255,\"" +
+                        "green\":...\nUnable to map json object value to class java.lang.String: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfStringFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"arrayOfString\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json array value: [2,3,5,7,11,1" +
+                        "3,17,19...\nUnable to parse json numeric value to class java.lang.String: 2");
+    }
+
+    @Test
+    public void arrayOfStringFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfString\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json array value: [true,false,t" +
+                        "rue,tru...\nUnable to parse json boolean value to class java.lang.String: true");
+    }
+
+    @Test
+    public void arrayOfNumberFromObject() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json object value: {\"red\":255,\"" +
+                        "green\":1...\nNumber[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfNumberFromString() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json string value: \"Supercalifr" +
+                        "agilisti...\nMissing a Converter for type class [Ljava.lang.Number; to convert the JSON String 'Super" +
+                        "califragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfNumberFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json numeric value: 12233344445" +
+                        "5555.6666...\nUnable to parse json numeric value to class [Ljava.lang.Number;: 122333444455555.6666.." +
+                        ".");
+    }
+
+    @Test
+    public void arrayOfNumberFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : true }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json boolean value: true\nUnable" +
+                        " to parse json boolean value to class [Ljava.lang.Number;: true");
+    }
+
+    @Test
+    public void arrayOfNumberFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json array value: [{\"red\":255,\"" +
+                        "green\":...\nNumber cannot be constructed to deserialize json object value: {\"red\":255,\"green\":1...\nja" +
+                        "va.lang.InstantiationException");
+    }
+
+    @Test
+    public void arrayOfNumberFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json array value: [\"Klaatu\",\"ba" +
+                        "rada\",\"...\nMissing a Converter for type class java.lang.Number to convert the JSON String 'Klaatu' ." +
+                        " Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfNumberFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfNumber\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json array value: [true,false,t" +
+                        "rue,tru...\nUnable to parse json boolean value to class java.lang.Number: true");
+    }
+
+    @Test
+    public void arrayOfBooleanFromObject() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json object value: {\"red\":255" +
+                        ",\"green\":1...\nBoolean[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfBooleanFromString() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json string value: \"Supercali" +
+                        "fragilisti...\nMissing a Converter for type class [Ljava.lang.Boolean; to convert the JSON String 'Su" +
+                        "percalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfBooleanFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json numeric value: 122333444" +
+                        "455555.6666...\nUnable to parse json numeric value to class [Ljava.lang.Boolean;: 122333444455555.666" +
+                        "6...");
+    }
+
+    @Test
+    public void arrayOfBooleanFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : true }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json boolean value: true\nUnab" +
+                        "le to parse json boolean value to class [Ljava.lang.Boolean;: true");
+    }
+
+    @Test
+    public void arrayOfBooleanFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json array value: [{\"red\":255" +
+                        ",\"green\":...\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfBooleanFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json array value: [\"Klaatu\",\"" +
+                        "barada\",\"...\nUnable to parse json string value to boolean: \"Klaatu\"");
+    }
+
+    @Test
+    public void arrayOfBooleanFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"arrayOfBoolean\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json array value: [2,3,5,7,11" +
+                        ",13,17,19...\nUnable to parse json numeric value to boolean: 2");
+    }
+
+    @Test
+    public void arrayOfIntFromObject() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json object value: {\"red\":255,\"green\"" +
+                        ":1...\nint[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfIntFromString() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json string value: \"Supercalifragilis" +
+                        "ti...\nMissing a Converter for type class [I to convert the JSON String 'Supercalifragilisticexpialid" +
+                        "ocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfIntFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json numeric value: 122333444455555.6" +
+                        "666...\nUnable to parse json numeric value to class [I: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfIntFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : true }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json boolean value: true\nUnable to pa" +
+                        "rse json boolean value to class [I: true");
+    }
+
+    @Test
+    public void arrayOfIntFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [{\"red\":255,\"green\"" +
+                        ":...\nUnable to map json object value to int: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfIntFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [\"Klaatu\",\"barada\"," +
+                        "\"...\nMissing a Converter for type int to convert the JSON String 'Klaatu' . Please register a custom" +
+                        " converter for it.");
+    }
+
+    @Test
+    public void arrayOfIntFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [true,false,true,tr" +
+                        "u...\nUnable to parse json boolean value to int: true");
+    }
+
+    @Test
+    public void arrayOfIntFromArrayOfNull() throws Exception {
+        assertMessage("{ \"arrayOfInt\" : [null,null,null,null,null,null] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [null,null,null,nul" +
+                        "l...\njson array mapped to int[] has null value at index 0");
+    }
+
+    @Test
+    public void arrayOfByteFromObject() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json object value: {\"red\":255,\"gree" +
+                        "n\":1...\nbyte[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfByteFromString() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json string value: \"Supercalifragil" +
+                        "isti...\nMissing a Converter for type class [B to convert the JSON String 'Supercalifragilisticexpial" +
+                        "idocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfByteFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json numeric value: 122333444455555" +
+                        ".6666...\nUnable to parse json numeric value to class [B: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfByteFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : true }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json boolean value: true\nUnable to " +
+                        "parse json boolean value to class [B: true");
+    }
+
+    @Test
+    public void arrayOfByteFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json array value: [{\"red\":255,\"gree" +
+                        "n\":...\nUnable to map json object value to byte: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfByteFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json array value: [\"Klaatu\",\"barada" +
+                        "\",\"...\nMissing a Converter for type byte to convert the JSON String 'Klaatu' . Please register a cus" +
+                        "tom converter for it.");
+    }
+
+    @Test
+    public void arrayOfByteFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfByte\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json array value: [true,false,true," +
+                        "tru...\nUnable to parse json boolean value to byte: true");
+    }
+
+    @Test
+    public void arrayOfCharFromObject() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json object value: {\"red\":255,\"gree" +
+                        "n\":1...\nchar[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfCharFromString() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json string value: \"Supercalifragil" +
+                        "isti...\nMissing a Converter for type class [C to convert the JSON String 'Supercalifragilisticexpial" +
+                        "idocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfCharFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json numeric value: 122333444455555" +
+                        ".6666...\nUnable to parse json numeric value to class [C: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfCharFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : true }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json boolean value: true\nUnable to " +
+                        "parse json boolean value to class [C: true");
+    }
+
+    @Test
+    public void arrayOfCharFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json array value: [{\"red\":255,\"gree" +
+                        "n\":...\nCannot cast org.apache.johnzon.core.JsonObjectImpl to javax.json.JsonString");
+    }
+
+    @Test
+    public void arrayOfCharFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfChar\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json array value: [true,false,true," +
+                        "tru...\nCannot cast javax.json.JsonValue$2 to javax.json.JsonString");
+    }
+
+    @Test
+    public void arrayOfShortFromObject() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json object value: {\"red\":255,\"gr" +
+                        "een\":1...\nshort[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfShortFromString() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json string value: \"Supercalifrag" +
+                        "ilisti...\nMissing a Converter for type class [S to convert the JSON String 'Supercalifragilisticexpi" +
+                        "alidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfShortFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json numeric value: 1223334444555" +
+                        "55.6666...\nUnable to parse json numeric value to class [S: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfShortFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : true }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json boolean value: true\nUnable t" +
+                        "o parse json boolean value to class [S: true");
+    }
+
+    @Test
+    public void arrayOfShortFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json array value: [{\"red\":255,\"gr" +
+                        "een\":...\nUnable to map json object value to short: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfShortFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json array value: [\"Klaatu\",\"bara" +
+                        "da\",\"...\nMissing a Converter for type short to convert the JSON String 'Klaatu' . Please register a " +
+                        "custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfShortFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfShort\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json array value: [true,false,tru" +
+                        "e,tru...\nUnable to parse json boolean value to short: true");
+    }
+
+    @Test
+    public void arrayOfLongFromObject() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json object value: {\"red\":255,\"gree" +
+                        "n\":1...\nlong[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfLongFromString() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json string value: \"Supercalifragil" +
+                        "isti...\nMissing a Converter for type class [J to convert the JSON String 'Supercalifragilisticexpial" +
+                        "idocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfLongFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json numeric value: 122333444455555" +
+                        ".6666...\nUnable to parse json numeric value to class [J: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfLongFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : true }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json boolean value: true\nUnable to " +
+                        "parse json boolean value to class [J: true");
+    }
+
+    @Test
+    public void arrayOfLongFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json array value: [{\"red\":255,\"gree" +
+                        "n\":...\nUnable to map json object value to long: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfLongFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json array value: [\"Klaatu\",\"barada" +
+                        "\",\"...\nMissing a Converter for type long to convert the JSON String 'Klaatu' . Please register a cus" +
+                        "tom converter for it.");
+    }
+
+    @Test
+    public void arrayOfLongFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfLong\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json array value: [true,false,true," +
+                        "tru...\nUnable to parse json boolean value to long: true");
+    }
+
+    @Test
+    public void arrayOfFloatFromObject() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json object value: {\"red\":255,\"gr" +
+                        "een\":1...\nfloat[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfFloatFromString() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json string value: \"Supercalifrag" +
+                        "ilisti...\nMissing a Converter for type class [F to convert the JSON String 'Supercalifragilisticexpi" +
+                        "alidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfFloatFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json numeric value: 1223334444555" +
+                        "55.6666...\nUnable to parse json numeric value to class [F: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfFloatFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : true }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json boolean value: true\nUnable t" +
+                        "o parse json boolean value to class [F: true");
+    }
+
+    @Test
+    public void arrayOfFloatFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json array value: [{\"red\":255,\"gr" +
+                        "een\":...\nUnable to map json object value to float: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfFloatFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json array value: [\"Klaatu\",\"bara" +
+                        "da\",\"...\nMissing a Converter for type float to convert the JSON String 'Klaatu' . Please register a " +
+                        "custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfFloatFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfFloat\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json array value: [true,false,tru" +
+                        "e,tru...\nUnable to parse json boolean value to float: true");
+    }
+
+    @Test
+    public void arrayOfDoubleFromObject() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json object value: {\"red\":255,\"" +
+                        "green\":1...\ndouble[] array not a suitable datatype for json object value: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfDoubleFromString() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json string value: \"Supercalifr" +
+                        "agilisti...\nMissing a Converter for type class [D to convert the JSON String 'Supercalifragilisticex" +
+                        "pialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfDoubleFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json numeric value: 12233344445" +
+                        "5555.6666...\nUnable to parse json numeric value to class [D: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfDoubleFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : true }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json boolean value: true\nUnable" +
+                        " to parse json boolean value to class [D: true");
+    }
+
+    @Test
+    public void arrayOfDoubleFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json array value: [{\"red\":255,\"" +
+                        "green\":...\nUnable to map json object value to double: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfDoubleFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json array value: [\"Klaatu\",\"ba" +
+                        "rada\",\"...\nMissing a Converter for type double to convert the JSON String 'Klaatu' . Please register" +
+                        " a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfDoubleFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"arrayOfDouble\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json array value: [true,false,t" +
+                        "rue,tru...\nUnable to parse json boolean value to double: true");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromObject() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json object value: {" +
+                        "\"red\":255,\"green\":1...\nboolean[] array not a suitable datatype for json object value: {\"red\":255,\"gr" +
+                        "een\":1...");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromString() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json string value: \"" +
+                        "Supercalifragilisti...\nMissing a Converter for type class [Z to convert the JSON String 'Supercalifr" +
+                        "agilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromNumber() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json numeric value: " +
+                        "122333444455555.6666...\nUnable to parse json numeric value to class [Z: 122333444455555.6666...");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromBoolean() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : true }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json boolean value: " +
+                        "true\nUnable to parse json boolean value to class [Z: true");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromArrayOfObject() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [{" +
+                        "\"red\":255,\"green\":...\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromArrayOfString() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [\"" +
+                        "Klaatu\",\"barada\",\"...\nUnable to parse json string value to boolean: \"Klaatu\"");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [2" +
+                        ",3,5,7,11,13,17,19...\nUnable to parse json numeric value to boolean: 2");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitiveFromArrayOfNull() throws Exception {
+        assertMessage("{ \"arrayOfBooleanPrimitive\" : [null,null,null,null,null,null] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [n" +
+                        "ull,null,null,null...\njson array mapped to boolean[] has null value at index 0");
+    }
+
+    @Test
+    public void listOfObjectFromObject() throws Exception {
+        assertMessage("{ \"listOfObject\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json object value: {\"red\":255" +
+                        ",\"green\":1...\nUnable to map json object value to java.util.List<org.apache.johnzon.mapper.Deserializa" +
+                        "tionExceptionMessagesTest$Color>: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void listOfObjectFromString() throws Exception {
+        assertMessage("{ \"listOfObject\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json string value: \"Supercali" +
+                        "fragilisti...\nMissing a Converter for type interface java.util.List to convert the JSON String 'Supe" +
+                        "rcalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfObjectFromNumber() throws Exception {
+        assertMessage("{ \"listOfObject\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json numeric value: 122333444" +
+                        "455555.6666...\nUnable to parse json numeric value to java.util.List<org.apache.johnzon.mapper.Deseria" +
+                        "lizationExceptionMessagesTest$Color>: 122333444455555.6666...");
+    }
+
+    @Test
+    public void listOfObjectFromBoolean() throws Exception {
+        assertMessage("{ \"listOfObject\" : true }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json boolean value: true\nUnab" +
+                        "le to parse json boolean value to java.util.List<org.apache.johnzon.mapper.DeserializationExceptionMe" +
+                        "ssagesTest$Color>: true");
+    }
+
+    @Test
+    public void listOfObjectFromArrayOfString() throws Exception {
+        assertMessage("{ \"listOfObject\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json array value: [\"Klaatu\",\"" +
+                        "barada\",\"...\nMissing a Converter for type class org.apache.johnzon.mapper.DeserializationExceptionMes" +
+                        "sagesTest$Color to convert the JSON String 'Klaatu' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfObjectFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"listOfObject\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json array value: [2,3,5,7,11" +
+                        ",13,17,19...\nUnable to parse json numeric value to class org.apache.johnzon.mapper.DeserializationExc" +
+                        "eptionMessagesTest$Color: 2");
+    }
+
+    @Test
+    public void listOfObjectFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"listOfObject\" : [true,false,true,true,false] }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json array value: [true,false" +
+                        ",true,tru...\nUnable to parse json boolean value to class org.apache.johnzon.mapper.DeserializationExc" +
+                        "eptionMessagesTest$Color: true");
+    }
+
+    @Test
+    public void listOfStringFromObject() throws Exception {
+        assertMessage("{ \"listOfString\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json object value: {\"red\":25" +
+                        "5,\"green\":1...\nUnable to map json object value to java.util.List<java.lang.String>: {\"red\":255,\"gree" +
+                        "n\":1...");
+    }
+
+    @Test
+    public void listOfStringFromString() throws Exception {
+        assertMessage("{ \"listOfString\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json string value: \"Supercal" +
+                        "ifragilisti...\nMissing a Converter for type interface java.util.List to convert the JSON String 'Sup" +
+                        "ercalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfStringFromNumber() throws Exception {
+        assertMessage("{ \"listOfString\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json numeric value: 12233344" +
+                        "4455555.6666...\nUnable to parse json numeric value to java.util.List<java.lang.String>: 122333444455" +
+                        "555.6666...");
+    }
+
+    @Test
+    public void listOfStringFromBoolean() throws Exception {
+        assertMessage("{ \"listOfString\" : true }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json boolean value: true\nUna" +
+                        "ble to parse json boolean value to java.util.List<java.lang.String>: true");
+    }
+
+    @Test
+    public void listOfStringFromArrayOfObject() throws Exception {
+        assertMessage("{ \"listOfString\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json array value: [{\"red\":25" +
+                        "5,\"green\":...\nUnable to map json object value to class java.lang.String: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void listOfStringFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"listOfString\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json array value: [2,3,5,7,1" +
+                        "1,13,17,19...\nUnable to parse json numeric value to class java.lang.String: 2");
+    }
+
+    @Test
+    public void listOfStringFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"listOfString\" : [true,false,true,true,false] }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json array value: [true,fals" +
+                        "e,true,tru...\nUnable to parse json boolean value to class java.lang.String: true");
+    }
+
+    @Test
+    public void listOfNumberFromObject() throws Exception {
+        assertMessage("{ \"listOfNumber\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json object value: {\"red\":25" +
+                        "5,\"green\":1...\nUnable to map json object value to java.util.List<java.lang.Number>: {\"red\":255,\"gree" +
+                        "n\":1...");
+    }
+
+    @Test
+    public void listOfNumberFromString() throws Exception {
+        assertMessage("{ \"listOfNumber\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json string value: \"Supercal" +
+                        "ifragilisti...\nMissing a Converter for type interface java.util.List to convert the JSON String 'Sup" +
+                        "ercalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfNumberFromNumber() throws Exception {
+        assertMessage("{ \"listOfNumber\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json numeric value: 12233344" +
+                        "4455555.6666...\nUnable to parse json numeric value to java.util.List<java.lang.Number>: 122333444455" +
+                        "555.6666...");
+    }
+
+    @Test
+    public void listOfNumberFromBoolean() throws Exception {
+        assertMessage("{ \"listOfNumber\" : true }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json boolean value: true\nUna" +
+                        "ble to parse json boolean value to java.util.List<java.lang.Number>: true");
+    }
+
+    @Test
+    public void listOfNumberFromArrayOfObject() throws Exception {
+        assertMessage("{ \"listOfNumber\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json array value: [{\"red\":25" +
+                        "5,\"green\":...\nNumber cannot be constructed to deserialize json object value: {\"red\":255,\"green\":1..." +
+                        "\njava.lang.InstantiationException");
+    }
+
+    @Test
+    public void listOfNumberFromArrayOfString() throws Exception {
+        assertMessage("{ \"listOfNumber\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json array value: [\"Klaatu\"," +
+                        "\"barada\",\"...\nMissing a Converter for type class java.lang.Number to convert the JSON String 'Klaatu" +
+                        "' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfNumberFromArrayOfBoolean() throws Exception {
+        assertMessage("{ \"listOfNumber\" : [true,false,true,true,false] }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json array value: [true,fals" +
+                        "e,true,tru...\nUnable to parse json boolean value to class java.lang.Number: true");
+    }
+
+    @Test
+    public void listOfBooleanFromObject() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json object value: {\"red\":" +
+                        "255,\"green\":1...\nUnable to map json object value to java.util.List<java.lang.Boolean>: {\"red\":255,\"g" +
+                        "reen\":1...");
+    }
+
+    @Test
+    public void listOfBooleanFromString() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json string value: \"Superc" +
+                        "alifragilisti...\nMissing a Converter for type interface java.util.List to convert the JSON String 'S" +
+                        "upercalifragilisticexpialidocious' . Please register a custom converter for it.");
+    }
+
+    @Test
+    public void listOfBooleanFromNumber() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json numeric value: 122333" +
+                        "444455555.6666...\nUnable to parse json numeric value to java.util.List<java.lang.Boolean>: 122333444" +
+                        "455555.6666...");
+    }
+
+    @Test
+    public void listOfBooleanFromBoolean() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : true }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json boolean value: true\nU" +
+                        "nable to parse json boolean value to java.util.List<java.lang.Boolean>: true");
+    }
+
+    @Test
+    public void listOfBooleanFromArrayOfObject() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json array value: [{\"red\":" +
+                        "255,\"green\":...\nUnable to parse json object value to boolean: {\"red\":255,\"green\":1...");
+    }
+
+    @Test
+    public void listOfBooleanFromArrayOfString() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json array value: [\"Klaatu" +
+                        "\",\"barada\",\"...\nUnable to parse json string value to boolean: \"Klaatu\"");
+    }
+
+    @Test
+    public void listOfBooleanFromArrayOfNumber() throws Exception {
+        assertMessage("{ \"listOfBoolean\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json array value: [2,3,5,7" +
+                        ",11,13,17,19...\nUnable to parse json numeric value to boolean: 2");
+    }
+
+    private void assertMessage(final String json, final String expected) throws Exception {
+        ExceptionAsserts.fromMapperReadObject(json, Widget.class)
+                .assertInstanceOf(MapperException.class)
+                .assertMessage(expected);
+    }
+
+    public static class Widget {
+        private Color[] arrayOfObject;
+        private String[] arrayOfString;
+        private Number[] arrayOfNumber;
+        private int[] arrayOfInt;
+        private byte[] arrayOfByte;
+        private char[] arrayOfChar;
+        private short[] arrayOfShort;
+        private long[] arrayOfLong;
+        private float[] arrayOfFloat;
+        private double[] arrayOfDouble;
+        private Boolean[] arrayOfBoolean;
+        private boolean[] arrayOfBooleanPrimitive;
+        private List<Color> listOfObject;
+        private List<String> listOfString;
+        private List<Number> listOfNumber;
+        private List<Boolean> listOfBoolean;
+        private Color object;
+        private String string;
+        private Integer number;
+        private int intPrimitive;
+        private Boolean bool;
+        private boolean boolPrimitive;
+        private Date date;
+        private TimeUnit unit;
+
+        public Color[] getArrayOfObject() {
+            return arrayOfObject;
+        }
+
+        public void setArrayOfObject(final Color[] arrayOfObject) {
+            this.arrayOfObject = arrayOfObject;
+        }
+
+        public String[] getArrayOfString() {
+            return arrayOfString;
+        }
+
+        public void setArrayOfString(final String[] arrayOfString) {
+            this.arrayOfString = arrayOfString;
+        }
+
+        public Number[] getArrayOfNumber() {
+            return arrayOfNumber;
+        }
+
+        public void setArrayOfNumber(final Number[] arrayOfNumber) {
+            this.arrayOfNumber = arrayOfNumber;
+        }
+
+        public int[] getArrayOfInt() {
+            return arrayOfInt;
+        }
+
+        public void setArrayOfInt(final int[] arrayOfInt) {
+            this.arrayOfInt = arrayOfInt;
+        }
+
+        public byte[] getArrayOfByte() {
+            return arrayOfByte;
+        }
+
+        public void setArrayOfByte(final byte[] arrayOfByte) {
+            this.arrayOfByte = arrayOfByte;
+        }
+
+        public char[] getArrayOfChar() {
+            return arrayOfChar;
+        }
+
+        public void setArrayOfChar(final char[] arrayOfChar) {
+            this.arrayOfChar = arrayOfChar;
+        }
+
+        public short[] getArrayOfShort() {
+            return arrayOfShort;
+        }
+
+        public void setArrayOfShort(final short[] arrayOfShort) {
+            this.arrayOfShort = arrayOfShort;
+        }
+
+        public long[] getArrayOfLong() {
+            return arrayOfLong;
+        }
+
+        public void setArrayOfLong(final long[] arrayOfLong) {
+            this.arrayOfLong = arrayOfLong;
+        }
+
+        public float[] getArrayOfFloat() {
+            return arrayOfFloat;
+        }
+
+        public void setArrayOfFloat(final float[] arrayOfFloat) {
+            this.arrayOfFloat = arrayOfFloat;
+        }
+
+        public double[] getArrayOfDouble() {
+            return arrayOfDouble;
+        }
+
+        public void setArrayOfDouble(final double[] arrayOfDouble) {
+            this.arrayOfDouble = arrayOfDouble;
+        }
+
+        public Boolean[] getArrayOfBoolean() {
+            return arrayOfBoolean;
+        }
+
+        public void setArrayOfBoolean(final Boolean[] arrayOfBoolean) {
+            this.arrayOfBoolean = arrayOfBoolean;
+        }
+
+        public boolean[] getArrayOfBooleanPrimitive() {
+            return arrayOfBooleanPrimitive;
+        }
+
+        public void setArrayOfBooleanPrimitive(final boolean[] arrayOfBooleanPrimitive) {
+            this.arrayOfBooleanPrimitive = arrayOfBooleanPrimitive;
+        }
+
+        public List<Color> getListOfObject() {
+            return listOfObject;
+        }
+
+        public void setListOfObject(final List<Color> listOfObject) {
+            this.listOfObject = listOfObject;
+        }
+
+        public List<String> getListOfString() {
+            return listOfString;
+        }
+
+        public void setListOfString(final List<String> listOfString) {
+            this.listOfString = listOfString;
+        }
+
+        public List<Number> getListOfNumber() {
+            return listOfNumber;
+        }
+
+        public void setListOfNumber(final List<Number> listOfNumber) {
+            this.listOfNumber = listOfNumber;
+        }
+
+        public List<Boolean> getListOfBoolean() {
+            return listOfBoolean;
+        }
+
+        public void setListOfBoolean(final List<Boolean> listOfBoolean) {
+            this.listOfBoolean = listOfBoolean;
+        }
+
+        public Color getObject() {
+            return object;
+        }
+
+        public void setObject(final Color object) {
+            this.object = object;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+
+        public Integer getNumber() {
+            return number;
+        }
+
+        public void setNumber(final Integer number) {
+            this.number = number;
+        }
+
+        public int getIntPrimitive() {
+            return intPrimitive;
+        }
+
+        public void setIntPrimitive(final int intPrimitive) {
+            this.intPrimitive = intPrimitive;
+        }
+
+        public Boolean getBool() {
+            return bool;
+        }
+
+        public void setBool(final Boolean bool) {
+            this.bool = bool;
+        }
+
+        public boolean isBoolPrimitive() {
+            return boolPrimitive;
+        }
+
+        public void setBoolPrimitive(final boolean boolPrimitive) {
+            this.boolPrimitive = boolPrimitive;
+        }
+
+        public Date getDate() {
+            return date;
+        }
+
+        public void setDate(final Date date) {
+            this.date = date;
+        }
+
+        public TimeUnit getUnit() {
+            return unit;
+        }
+
+        public void setUnit(final TimeUnit unit) {
+            this.unit = unit;
+        }
+    }
+
+    public static class Color {
+        int red;
+        int green;
+        int blue;
+
+        public Color() {
+        }
+
+        public int getRed() {
+            return red;
+        }
+
+        public void setRed(final int red) {
+            this.red = red;
+        }
+
+        public int getGreen() {
+            return green;
+        }
+
+        public void setGreen(final int green) {
+            this.green = green;
+        }
+
+        public int getBlue() {
+            return blue;
+        }
+
+        public void setBlue(final int blue) {
+            this.blue = blue;
+        }
+    }
+}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ExceptionAsserts.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ExceptionAsserts.java
new file mode 100644
index 0000000..8cb1f5e
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ExceptionAsserts.java
@@ -0,0 +1,106 @@
+/*
+ * 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.johnzon.mapper;
+
+import org.junit.Assert;
+
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Type;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ExceptionAsserts {
+
+    private final Throwable throwable;
+
+    public ExceptionAsserts(final Throwable throwable) {
+        this.throwable = throwable;
+    }
+
+    public <T extends Throwable> ExceptionAsserts assertInstanceOf(final Class<T> expected) {
+        final String message = String.format("%s not an instance of %s",
+                throwable.getClass().getSimpleName(),
+                expected.getSimpleName());
+        assertTrue(message, expected.isAssignableFrom(throwable.getClass()));
+        return this;
+    }
+
+    public ExceptionAsserts assertSame(final Throwable expected) {
+        Assert.assertSame(expected, throwable);
+        return this;
+    }
+    
+    public ExceptionAsserts assertCauseChain(final Throwable expected) {
+        Throwable cause = throwable;
+        while ((cause = cause.getCause()) != null) {
+            if (cause == expected) {
+                return this;
+            }
+        }
+
+        throw new AssertionError("Throwable " + throwable.getClass().getSimpleName() +
+                " cause chain does not contain exception:" + expected.getMessage(), throwable);
+    }
+
+    public ExceptionAsserts assertMessage(final String expected) {
+        assertEquals(expected, throwable.getMessage());
+        return this;
+    }
+
+    /**
+     * Useful for debugging tests
+     */
+    public ExceptionAsserts printStackTrace() {
+        throwable.printStackTrace();
+        return this;
+    }
+
+    public Throwable getThrowable() {
+        return throwable;
+    }
+
+    public static ExceptionAsserts from(final Runnable runnable) {
+        try {
+
+            runnable.run();
+
+            throw new AssertionError("No exception occurred");
+
+        } catch (AssertionError assertionError) {
+            throw assertionError;
+        } catch (Throwable throwable) {
+            return new ExceptionAsserts(throwable);
+        }
+    }
+
+    public static ExceptionAsserts fromMapperReadObject(final String json, final Type clazz) {
+        return from(() -> {
+            try (final Mapper mapper = new MapperBuilder().setSnippetMaxLength(20).build()) {
+                mapper.readObject(json, clazz);
+            }
+        });
+    }
+
+    public static ExceptionAsserts fromMapperWriteObject(final Object object) {
+        return from(() -> {
+            try (final Mapper mapper = new MapperBuilder().setSnippetMaxLength(20).build()) {
+                mapper.writeObject(object, new ByteArrayOutputStream());
+            }
+        });
+    }
+}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperAdapterExceptionsTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperAdapterExceptionsTest.java
new file mode 100644
index 0000000..2d9c860
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperAdapterExceptionsTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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.johnzon.mapper;
+
+import org.junit.Test;
+
+import java.util.concurrent.Callable;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class MapperAdapterExceptionsTest {
+
+    private static final RuntimeException FROM_EXCEPTION = new RuntimeException("I am user, hear me roar");
+    private static final RuntimeException TO_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void adapterFromRuntimeException() {
+
+        final Runnable adapterFrom = () -> {
+            try (final Mapper mapper = new MapperBuilder().addAdapter(new FailingAdapter()).setSnippetMaxLength(20).build()) {
+                mapper.writeObjectAsString(new Widget(new Color("red")));
+            }
+        };
+
+        ExceptionAsserts.from(adapterFrom)
+                // TODO: not consistent with how getter user exceptions are handled
+                .assertSame(FROM_EXCEPTION);
+    }
+
+    @Test
+    public void adapterToRuntimeException() {
+        
+        final Runnable adapterTo = () -> {
+            try (final Mapper mapper = new MapperBuilder().addAdapter(new FailingAdapter()).setSnippetMaxLength(20).build()) {
+                mapper.readObject("{\"color\":{\"red\":2550,\"green\":0,\"blue\":0}}", Widget.class);
+            }
+        };
+        
+        ExceptionAsserts.from(adapterTo)
+                .assertCauseChain(TO_EXCEPTION)
+                .assertInstanceOf(MapperException.class)
+                .assertMessage("Widget property 'color' of type Color cannot be mapped to json object value: {\"red\":2550,\"green\":...\n" +
+                        "I am user, hear me roar");
+    }
+
+    @Test
+    public void adapterFromNulValue() {
+
+        final Runnable adapterFrom = () -> {
+            try (final Mapper mapper = new MapperBuilder().addAdapter(new ReturnNull()).setSnippetMaxLength(20).build()) {
+                mapper.writeObjectAsString(new Widget(new Color("red")));
+            }
+        };
+
+        ExceptionAsserts.from(adapterFrom)
+                // TODO Review: to() can return null, but from() cannot
+                .assertInstanceOf(NullPointerException.class);
+
+    }
+
+    @Test
+    public void adapterToNullValue() throws Exception {
+
+        final Callable<Widget> adapterTo = () -> {
+            try (final Mapper mapper = new MapperBuilder().addAdapter(new ReturnNull()).setSnippetMaxLength(20).build()) {
+                return mapper.readObject("{\"color\":{\"red\":2550,\"green\":0,\"blue\":0}}", Widget.class);
+            }
+        };
+
+        final Widget widget = adapterTo.call();
+
+        assertNotNull(widget);
+        assertNull(widget.getColor());
+    }
+
+    public static class FailingAdapter implements Adapter<Color, RGB> {
+
+        // writeObject
+        @Override
+        public RGB from(final Color color) {
+            throw FROM_EXCEPTION;
+        }
+
+        // readObject
+        @Override
+        public Color to(final RGB rgb) {
+            throw TO_EXCEPTION;
+        }
+
+    }
+
+    public static class ReturnNull implements Adapter<Color, RGB> {
+
+        // writeObject
+        @Override
+        public RGB from(final Color color) {
+            return null;
+        }
+
+        // readObject
+        @Override
+        public Color to(final RGB rgb) {
+            return null;
+        }
+    }
+
+    public static class Widget {
+        private Color color;
+
+        public Widget() {
+        }
+
+        public Widget(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class Color {
+        private final String name;
+
+        public Color(final String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    public static class RGB {
+        private int red;
+        private int green;
+        private int blue;
+
+        public RGB() {
+        }
+
+        public RGB(final int red, final int green, final int blue) {
+            this.red = red;
+            this.green = green;
+            this.blue = blue;
+        }
+
+        public int getRed() {
+            return red;
+        }
+
+        public void setRed(final int red) {
+            this.red = red;
+        }
+
+        public int getGreen() {
+            return green;
+        }
+
+        public void setGreen(final int green) {
+            this.green = green;
+        }
+
+        public int getBlue() {
+            return blue;
+        }
+
+        public void setBlue(final int blue) {
+            this.blue = blue;
+        }
+
+    }
+
+}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanConstructorExceptionsTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanConstructorExceptionsTest.java
new file mode 100644
index 0000000..2615fe0
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanConstructorExceptionsTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.johnzon.mapper;
+
+import org.junit.Test;
+
+import java.beans.ConstructorProperties;
+import java.lang.reflect.Type;
+
+public class MapperBeanConstructorExceptionsTest {
+
+    private static final RuntimeException USER_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void constructor() {
+        ExceptionAsserts.fromMapperReadObject("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Circle.class)
+                .assertInstanceOf(MapperException.class)
+                .assertCauseChain(USER_EXCEPTION)
+                .assertMessage("Circle cannot be constructed to deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    @Test
+    public void constructorParametersWithNoAnnotations() {
+        ExceptionAsserts.fromMapperReadObject("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Square.class)
+                .assertInstanceOf(MapperException.class)
+                .assertMessage("Square has no suitable constructor or factory.  Cannot deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "Use Johnzon @ConstructorProperties or @JsonbCreator if constructor arguments are needed\n" +
+                        "class org.apache.johnzon.mapper.MapperBeanConstructorExceptionsTest$Square not instantiable");
+    }
+
+    @Test
+    public void constructorWithGenerics() {
+
+        final Type type = new Oval<String>(true) {
+        }.getClass().getGenericSuperclass();
+
+        ExceptionAsserts.fromMapperReadObject("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", type)
+                .assertInstanceOf(MapperException.class)
+                .assertCauseChain(USER_EXCEPTION)
+                .assertMessage("Oval<String> cannot be constructed to deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    @Test
+    public void constructorProperties() {
+        ExceptionAsserts.fromMapperReadObject("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Triangle.class)
+                .assertInstanceOf(MapperException.class)
+                .assertCauseChain(USER_EXCEPTION)
+                .assertMessage("Triangle cannot be constructed to deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    @Test
+    public void noConstructors() {
+        ExceptionAsserts.fromMapperReadObject("{ \"string\" : \"Supercalifragilisticexpialidocious\" }", Sphere.class)
+                .assertInstanceOf(MapperException.class)
+                .assertMessage("Sphere is an interface and requires an adapter or factory.  Cannot deserialize json object value: {\"string\":\"Supercali...\n" +
+                        "interface org.apache.johnzon.mapper.MapperBeanConstructorExceptionsTest$Sphere not instantiable");
+    }
+
+    public static class Circle {
+        private String string;
+
+        public Circle() {
+            throw USER_EXCEPTION;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+    }
+
+    public static class Square {
+        private String string;
+
+        public Square(final String string) {
+            throw USER_EXCEPTION;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+    }
+
+    public static class Oval<T> {
+        private String s;
+
+        public Oval() {
+            throw USER_EXCEPTION;
+        }
+
+        public Oval(final boolean ignored) {
+        }
+    }
+
+    public static class Triangle {
+        private String string;
+
+        @ConstructorProperties("string")
+        public Triangle(final String string) {
+            throw USER_EXCEPTION;
+        }
+    }
+
+    public interface Sphere {
+    }
+
+
+}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanGetterUserExceptionsTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanGetterUserExceptionsTest.java
new file mode 100644
index 0000000..57b620f
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanGetterUserExceptionsTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.johnzon.mapper;
+
+import org.junit.Test;
+
+public class MapperBeanGetterUserExceptionsTest {
+
+    private static final RuntimeException USER_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void object() {
+        ExceptionAsserts.fromMapperWriteObject(new Widget())
+                .assertInstanceOf(MapperException.class)
+                .assertMessage("Error calling public java.lang.String org.apache.johnzon.mapper.MapperBeanGetter" +
+                        "UserExceptionsTest$Widget.getString()")
+                .assertCauseChain(USER_EXCEPTION);
+    }
+
+    public static class Widget {
+        private String string;
+
+        public String getString() {
+            throw USER_EXCEPTION;
+        }
+
+        public void setString(final String string) {
+            this.string = string;
+        }
+    }
+}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanSetterUserExceptionsTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanSetterUserExceptionsTest.java
new file mode 100644
index 0000000..e4727c7
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperBeanSetterUserExceptionsTest.java
@@ -0,0 +1,478 @@
+/*
+ * 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.johnzon.mapper;
+
+import org.junit.Test;
+
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class MapperBeanSetterUserExceptionsTest {
+
+    private static final RuntimeException USER_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void object() {
+        assertException("{ \"object\" : {\"red\": 255, \"green\": 165, \"blue\":0} }",
+                "Widget property 'object' of type Color cannot be mapped to json object value: {\"red\":255,\"green\":1.." +
+                        ".\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setObjec" +
+                        "t(org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Color)");
+    }
+
+    @Test
+    public void string() {
+        assertException("{ \"string\" : \"Supercalifragilisticexpialidocious\" }",
+                "Widget property 'string' of type String cannot be mapped to json string value: \"Supercalifragilisti." +
+                        "..\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setStri" +
+                        "ng(java.lang.String)");
+    }
+
+    @Test
+    public void number() {
+        assertException("{ \"number\" : 122333444455555.666666777777788888888 }",
+                "Widget property 'number' of type Double cannot be mapped to json numeric value: 122333444455555.6666" +
+                        "...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setNum" +
+                        "ber(java.lang.Double)");
+    }
+
+    @Test
+    public void intPrimitive() {
+        assertException("{ \"intPrimitive\" : 42 }",
+                "Widget property 'intPrimitive' of type int cannot be mapped to json numeric value: 42\nError calling " +
+                        "public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setIntPrimitive(int)");
+    }
+
+    @Test
+    public void booleanValue() {
+        assertException("{ \"bool\" : true }",
+                "Widget property 'bool' of type Boolean cannot be mapped to json boolean value: true\nError calling pu" +
+                        "blic void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setBool(java.lang.Boolean)");
+    }
+
+    @Test
+    public void boolPrimitive() {
+        assertException("{ \"boolPrimitive\" : true }",
+                "Widget property 'boolPrimitive' of type boolean cannot be mapped to json boolean value: true\nError c" +
+                        "alling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setBoolPrimitive(" +
+                        "boolean)");
+    }
+
+    @Test
+    public void enumeration() {
+        assertException("{ \"unit\" : \"SECONDS\" }",
+                "Widget property 'unit' of type TimeUnit cannot be mapped to json string value: \"SECONDS\"\nError calli" +
+                        "ng public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setUnit(java.util.con" +
+                        "current.TimeUnit)");
+    }
+
+    @Test
+    public void date() {
+        assertException("{ \"date\" : \"20220503123456UTC\" }",
+                "Widget property 'date' of type Date cannot be mapped to json string value: \"20220503123456UTC\"\nError" +
+                        " calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setDate(java.ut" +
+                        "il.Date)");
+    }
+
+    @Test
+    public void arrayOfObject() {
+        assertException("{ \"arrayOfObject\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'arrayOfObject' of type Color[] cannot be mapped to json array value: [{\"red\":255,\"g" +
+                        "reen\":...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget." +
+                        "setArrayOfObject(org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Color[])");
+    }
+
+    @Test
+    public void arrayOfString() {
+        assertException("{ \"arrayOfString\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'arrayOfString' of type String[] cannot be mapped to json array value: [\"Klaatu\",\"ba" +
+                        "rada\",\"...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget" +
+                        ".setArrayOfString(java.lang.String[])");
+    }
+
+    @Test
+    public void arrayOfNumber() {
+        assertException("{ \"arrayOfNumber\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfNumber' of type Number[] cannot be mapped to json array value: [2,3,5,7,11,1" +
+                        "3,17,19...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget" +
+                        ".setArrayOfNumber(java.lang.Number[])");
+    }
+
+    @Test
+    public void arrayOfBoolean() {
+        assertException("{ \"arrayOfBoolean\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfBoolean' of type Boolean[] cannot be mapped to json array value: [true,false" +
+                        ",true,tru...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widg" +
+                        "et.setArrayOfBoolean(java.lang.Boolean[])");
+    }
+
+    @Test
+    public void arrayOfInt() {
+        assertException("{ \"arrayOfInt\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfInt' of type int[] cannot be mapped to json array value: [2,3,5,7,11,13,17,1" +
+                        "9...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.setAr" +
+                        "rayOfInt(int[])");
+    }
+
+    @Test
+    public void arrayOfByte() {
+        assertException("{ \"arrayOfByte\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfByte' of type byte[] cannot be mapped to json array value: [2,3,5,7,11,13,17" +
+                        ",19...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.set" +
+                        "ArrayOfByte(byte[])");
+    }
+
+    @Test
+    public void arrayOfChar() {
+        assertException("{ \"arrayOfChar\" : [\"a\",\"a\",\"a\",\"a\",\"a\",\"a\",\"a\",\"a\"] }",
+                "Widget property 'arrayOfChar' of type char[] cannot be mapped to json array value: [\"a\",\"a\",\"a\",\"a\"," +
+                        "\"a\"...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.set" +
+                        "ArrayOfChar(char[])");
+    }
+
+    @Test
+    public void arrayOfShort() {
+        assertException("{ \"arrayOfShort\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfShort' of type short[] cannot be mapped to json array value: [2,3,5,7,11,13," +
+                        "17,19...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.s" +
+                        "etArrayOfShort(short[])");
+    }
+
+    @Test
+    public void arrayOfLong() {
+        assertException("{ \"arrayOfLong\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfLong' of type long[] cannot be mapped to json array value: [2,3,5,7,11,13,17" +
+                        ",19...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.set" +
+                        "ArrayOfLong(long[])");
+    }
+
+    @Test
+    public void arrayOfFloat() {
+        assertException("{ \"arrayOfFloat\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfFloat' of type float[] cannot be mapped to json array value: [2,3,5,7,11,13," +
+                        "17,19...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget.s" +
+                        "etArrayOfFloat(float[])");
+    }
+
+    @Test
+    public void arrayOfDouble() {
+        assertException("{ \"arrayOfDouble\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'arrayOfDouble' of type double[] cannot be mapped to json array value: [2,3,5,7,11,1" +
+                        "3,17,19...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widget" +
+                        ".setArrayOfDouble(double[])");
+    }
+
+    @Test
+    public void arrayOfBooleanPrimitive() {
+        assertException("{ \"arrayOfBooleanPrimitive\" : [true,false,true,true,false] }",
+                "Widget property 'arrayOfBooleanPrimitive' of type boolean[] cannot be mapped to json array value: [t" +
+                        "rue,false,true,tru...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptions" +
+                        "Test$Widget.setArrayOfBooleanPrimitive(boolean[])");
+    }
+
+    @Test
+    public void listOfObject() {
+        assertException("{ \"listOfObject\" : [{\"red\": 255, \"green\": 165, \"blue\":0},{\"red\": 0, \"green\": 45, \"blue\":127}] }",
+                "Widget property 'listOfObject' of type List<Color> cannot be mapped to json array value: [{\"red\":255" +
+                        ",\"green\":...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Widg" +
+                        "et.setListOfObject(java.util.List)");
+    }
+
+    @Test
+    public void listOfString() {
+        assertException("{ \"listOfString\" : [\"Klaatu\", \"barada\", \"nikto\"] }",
+                "Widget property 'listOfString' of type List<String> cannot be mapped to json array value: [\"Klaatu\"," +
+                        "\"barada\",\"...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Wid" +
+                        "get.setListOfString(java.util.List)");
+    }
+
+    @Test
+    public void listOfNumber() {
+        assertException("{ \"listOfNumber\" : [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] }",
+                "Widget property 'listOfNumber' of type List<Number> cannot be mapped to json array value: [2,3,5,7,1" +
+                        "1,13,17,19...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$Wid" +
+                        "get.setListOfNumber(java.util.List)");
+    }
+
+    @Test
+    public void listOfBoolean() {
+        assertException("{ \"listOfBoolean\" : [true,false,true,true,false] }",
+                "Widget property 'listOfBoolean' of type List<Boolean> cannot be mapped to json array value: [true,fa" +
+                        "lse,true,tru...\nError calling public void org.apache.johnzon.mapper.MapperBeanSetterUserExceptionsTest$W" +
+                        "idget.setListOfBoolean(java.util.List)");
+    }
+
+    private void assertException(final String json, final String expected) {
+        ExceptionAsserts.fromMapperReadObject(json, Widget.class)
+                .assertInstanceOf(MapperException.class)
+                .assertMessage(expected)
+                .assertCauseChain(USER_EXCEPTION);
+    }
+
+    public static class Widget {
+        private Color[] arrayOfObject;
+        private String[] arrayOfString;
+        private Number[] arrayOfNumber;
+        private int[] arrayOfInt;
+        private byte[] arrayOfByte;
+        private char[] arrayOfChar;
+        private short[] arrayOfShort;
+        private long[] arrayOfLong;
+        private float[] arrayOfFloat;
+        private double[] arrayOfDouble;
+        private Boolean[] arrayOfBoolean;
+        private boolean[] arrayOfBooleanPrimitive;
+        private List<Color> listOfObject;
+        private List<String> listOfString;
+        private List<Number> listOfNumber;
+        private List<Boolean> listOfBoolean;
+        private Color object;
+        private String string;
+        private Double number;
+        private int intPrimitive;
+        private Boolean bool;
+        private boolean boolPrimitive;
+        private Date date;
+        private TimeUnit unit;
+
+        public Color[] getArrayOfObject() {
+            return arrayOfObject;
+        }
+
+        public void setArrayOfObject(final Color[] arrayOfObject) {
+            throw USER_EXCEPTION;
+        }
+
+        public String[] getArrayOfString() {
+            return arrayOfString;
+        }
+
+        public void setArrayOfString(final String[] arrayOfString) {
+            throw USER_EXCEPTION;
+        }
+
+        public Number[] getArrayOfNumber() {
+            return arrayOfNumber;
+        }
+
+        public void setArrayOfNumber(final Number[] arrayOfNumber) {
+            throw USER_EXCEPTION;
+        }
+
+        public int[] getArrayOfInt() {
+            return arrayOfInt;
+        }
+
+        public void setArrayOfInt(final int[] arrayOfint) {
+            throw USER_EXCEPTION;
+        }
+
+        public Boolean[] getArrayOfBoolean() {
+            return arrayOfBoolean;
+        }
+
+        public void setArrayOfBoolean(final Boolean[] arrayOfBoolean) {
+            throw USER_EXCEPTION;
+        }
+
+        public boolean[] getArrayOfBooleanPrimitive() {
+            return arrayOfBooleanPrimitive;
+        }
+
+        public void setArrayOfBooleanPrimitive(final boolean[] arrayOfBooleanPrimitive) {
+            throw USER_EXCEPTION;
+        }
+
+        public Color getObject() {
+            return object;
+        }
+
+        public void setObject(final Color object) {
+            throw USER_EXCEPTION;
+        }
+
+        public String getString() {
+            return string;
+        }
+
+        public void setString(final String string) {
+            throw USER_EXCEPTION;
+        }
+
+        public Double getNumber() {
+            return number;
+        }
+
+        public void setNumber(final Double number) {
+            throw USER_EXCEPTION;
+        }
+
+        public int getIntPrimitive() {
+            return intPrimitive;
+        }
+
+        public void setIntPrimitive(final int intPrimitive) {
+            throw USER_EXCEPTION;
+        }
+
+        public Boolean getBool() {
+            return bool;
+        }
+
+        public void setBool(final Boolean bool) {
+            throw USER_EXCEPTION;
+        }
+
+        public boolean isBoolPrimitive() {
+            return boolPrimitive;
+        }
+
+        public void setBoolPrimitive(final boolean boolPrimitive) {
+            throw USER_EXCEPTION;
+        }
+
+        public Date getDate() {
+            return date;
+        }
+
+        public void setDate(final Date date) {
+            throw USER_EXCEPTION;
+        }
+
+        public TimeUnit getUnit() {
+            return unit;
+        }
+
+        public void setUnit(final TimeUnit unit) {
+            throw USER_EXCEPTION;
+        }
+
+        public byte[] getArrayOfByte() {
+            return arrayOfByte;
+        }
+
+        public void setArrayOfByte(final byte[] arrayOfByte) {
+            throw USER_EXCEPTION;
+        }
+
+        public char[] getArrayOfChar() {
+            return arrayOfChar;
+        }
+
+        public void setArrayOfChar(final char[] arrayOfChar) {
+            throw USER_EXCEPTION;
+        }
+
+        public short[] getArrayOfShort() {
+            return arrayOfShort;
+        }
+
+        public void setArrayOfShort(final short[] arrayOfShort) {
+            throw USER_EXCEPTION;
+        }
+
+        public long[] getArrayOfLong() {
+            return arrayOfLong;
+        }
+
+        public void setArrayOfLong(final long[] arrayOfLong) {
+            throw USER_EXCEPTION;
+        }
+
+        public float[] getArrayOfFloat() {
+            return arrayOfFloat;
+        }
+
+        public void setArrayOfFloat(final float[] arrayOfFloat) {
+            throw USER_EXCEPTION;
+        }
+
+        public double[] getArrayOfDouble() {
+            return arrayOfDouble;
+        }
+
+        public void setArrayOfDouble(final double[] arrayOfDouble) {
+            throw USER_EXCEPTION;
+        }
+
+        public List<Color> getListOfObject() {
+            return listOfObject;
+        }
+
+        public void setListOfObject(final List<Color> listOfObject) {
+            throw USER_EXCEPTION;
+        }
+
+        public List<String> getListOfString() {
+            return listOfString;
+        }
+
+        public void setListOfString(final List<String> listOfString) {
+            throw USER_EXCEPTION;
+        }
+
+        public List<Number> getListOfNumber() {
+            return listOfNumber;
+        }
+
+        public void setListOfNumber(final List<Number> listOfNumber) {
+            throw USER_EXCEPTION;
+        }
+
+        public List<Boolean> getListOfBoolean() {
+            return listOfBoolean;
+        }
+
+        public void setListOfBoolean(final List<Boolean> listOfBoolean) {
+            throw USER_EXCEPTION;
+        }
+
+    }
+
+    public static class Color {
+        int red;
+        int green;
+        int blue;
+
+        public Color() {
+        }
+
+        public int getRed() {
+            return red;
+        }
+
+        public void setRed(final int red) {
+            this.red = red;
+        }
+
+        public int getGreen() {
+            return green;
+        }
+
+        public void setGreen(final int green) {
+            this.green = green;
+        }
+
+        public int getBlue() {
+            return blue;
+        }
+
+        public void setBlue(final int blue) {
+            this.blue = blue;
+        }
+    }
+}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConverterExceptionsTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConverterExceptionsTest.java
new file mode 100644
index 0000000..321478b
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConverterExceptionsTest.java
@@ -0,0 +1,215 @@
+/*
+ * 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.johnzon.mapper;
+
+import org.junit.Test;
+
+import java.util.concurrent.Callable;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class MapperConverterExceptionsTest {
+
+    private static final RuntimeException FROM_STRING_EXCEPTION = new RuntimeException("I am user, hear me roar");
+    private static final RuntimeException TO_STRING_EXCEPTION = new RuntimeException("I am user, hear me roar");
+    private static final RuntimeException CONSTRUCTOR_EXCEPTION = new RuntimeException("I am user, hear me roar");
+
+    @Test
+    public void failedConstructorWriteObject() {
+        final Object object = new WidgetWithFailedConstructorConverter(new Color("orange"));
+        
+        ExceptionAsserts.fromMapperWriteObject(object)
+                .assertCauseChain(CONSTRUCTOR_EXCEPTION)
+                // TODO wrapped, but not wrapped with MapperException
+                .assertInstanceOf(IllegalArgumentException.class)
+                .assertMessage("java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    @Test
+    public void failedConstructorReadObject() {
+        final String json = "{\"color\": \"Supercalifragilisticexpialidocious\" }";
+        ExceptionAsserts.fromMapperReadObject(json, WidgetWithFailedConstructorConverter.class)
+                .assertCauseChain(CONSTRUCTOR_EXCEPTION)
+                // TODO Review: wrapped, but not wrapped with MapperException and no json is printed
+                .assertInstanceOf(IllegalArgumentException.class)
+                .assertMessage("java.lang.RuntimeException: I am user, hear me roar");
+    }
+
+    @Test
+    public void failedToString() {
+        final Object object = new WidgetWithFailedConverter(new Color("orange"));
+
+        ExceptionAsserts.fromMapperWriteObject(object)
+                // TODO Review
+                .assertSame(TO_STRING_EXCEPTION);
+    }
+
+    @Test
+    public void failedFromString() {
+        final String json = "{\"color\": \"Supercalifragilisticexpialidocious\" }";
+
+        ExceptionAsserts.fromMapperReadObject(json, WidgetWithFailedConverter.class)
+                .assertCauseChain(FROM_STRING_EXCEPTION)
+                .assertInstanceOf(MapperException.class)
+                .assertMessage("WidgetWithFailedConverter property 'color' of type Color cannot be " +
+                        "mapped to json string value: \"Supercalifragilisti...\n" +
+                        "I am user, hear me roar");
+    }
+
+    @Test
+    public void nullToString() {
+        final Object object = new WidgetWithNullConverter(new Color("orange"));
+
+        ExceptionAsserts.fromMapperWriteObject(object)
+                // TODO Review: fromString can return null, but toString cannot
+                .assertInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void nullFromString() throws Exception {
+        final String json = "{\"color\": \"Supercalifragilisticexpialidocious\" }";
+
+
+        final Callable<WidgetWithNullConverter> fromString = () -> {
+            try (final Mapper mapper = new MapperBuilder().setSnippetMaxLength(20).build()) {
+                return mapper.readObject(json, WidgetWithNullConverter.class);
+            }
+        };
+
+        final WidgetWithNullConverter widget = fromString.call();
+
+        assertNotNull(widget);
+        assertNull(widget.getColor());
+    }
+
+    public static class NullConverter implements Converter<Color> {
+        @Override
+        public String toString(final Color instance) {
+            return null;
+        }
+
+        @Override
+        public Color fromString(final String text) {
+            return null;
+        }
+    }
+
+    public static class FailedConverter implements Converter<Color> {
+        @Override
+        public String toString(final Color instance) {
+            throw TO_STRING_EXCEPTION;
+        }
+
+        @Override
+        public Color fromString(final String text) {
+            throw FROM_STRING_EXCEPTION;
+        }
+    }
+
+    public static class FailedConstructorConverter implements Converter<Color> {
+
+        public FailedConstructorConverter() {
+            throw CONSTRUCTOR_EXCEPTION;
+        }
+
+        @Override
+        public String toString(final Color instance) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Color fromString(final String text) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public static class WidgetWithFailedConstructorConverter {
+
+        @JohnzonConverter(FailedConstructorConverter.class)
+        private Color color;
+
+        public WidgetWithFailedConstructorConverter() {
+        }
+
+        public WidgetWithFailedConstructorConverter(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class WidgetWithNullConverter {
+
+        @JohnzonConverter(NullConverter.class)
+        private Color color;
+
+        public WidgetWithNullConverter() {
+        }
+
+        public WidgetWithNullConverter(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class WidgetWithFailedConverter {
+
+        @JohnzonConverter(FailedConverter.class)
+        private Color color;
+
+        public WidgetWithFailedConverter() {
+        }
+
+        public WidgetWithFailedConverter(final Color color) {
+            this.color = color;
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public void setColor(final Color color) {
+            this.color = color;
+        }
+    }
+
+    public static class Color {
+        private final String name;
+
+        public Color(final String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/TypeSimpleNameTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/TypeSimpleNameTest.java
new file mode 100644
index 0000000..f94a4a3
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/TypeSimpleNameTest.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.johnzon.mapper;
+
+import org.junit.Test;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.function.Function;
+
+import static org.apache.johnzon.mapper.ExceptionMessages.simpleName;
+import static org.junit.Assert.assertEquals;
+
+public class TypeSimpleNameTest {
+
+    @Test
+    public void clazz() {
+        assertEquals("URI", simpleName(URI.class));
+    }
+
+    @Test
+    public void innerClazz() {
+        assertEquals("Simple$Nam3", simpleName(Simple$Nam3.class));
+    }
+
+    @Test
+    public void parameterizedType() throws NoSuchFieldException {
+        class Foo {
+            Function<Simple$Nam3, Simple$Nam3> field;
+        }
+        final Type type = Foo.class.getDeclaredField("field").getGenericType();
+
+        assertEquals("Function<Simple$Nam3,Simple$Nam3>", simpleName(type));
+    }
+
+    @Test
+    public void genericArrayType() throws Exception {
+        class Foo {
+            Function<Simple$Nam3, Simple$Nam3>[] field;
+        }
+        final Type type = Foo.class.getDeclaredField("field").getGenericType();
+
+        assertEquals("Function<Simple$Nam3,Simple$Nam3>[]", simpleName(type));
+    }
+
+    @Test
+    public void wildcardArrayType() throws Exception {
+        class Foo {
+            Function<? extends Simple$Nam3, ? super Simple$Nam3> field;
+        }
+        final Type type = Foo.class.getDeclaredField("field").getGenericType();
+
+        final String actual = simpleName(type);
+        assertEquals("Function<? extends Simple$Nam3,? super Simple$Nam3>", actual);
+    }
+
+    @Test
+    public void fallback() {
+        final Type unsupportedType = new Type() {
+            @Override
+            public String getTypeName() {
+                return "we.don't.know.what.it.might$Contain.123";
+            }
+        };
+
+        assertEquals("we.don't.know.what.it.might$Contain.123", simpleName(unsupportedType));
+    }
+
+    //CHECKSTYLE:OFF
+    public static class Simple$Nam3 {
+
+    }
+    //CHECKSTYLE:ON
+}