JOHNZON-367 Tests that johnzon.snippetMaxLength works as expected
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/Snippet.java b/johnzon-core/src/main/java/org/apache/johnzon/core/Snippet.java
index 356762d..a979c45 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/Snippet.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/Snippet.java
@@ -24,7 +24,6 @@
 import javax.json.stream.JsonGeneratorFactory;
 import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
-import java.io.Flushable;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.UncheckedIOException;
@@ -63,13 +62,22 @@
         return new Snippet(max).of(value);
     }
 
-    class Buffer implements Flushable, Closeable {
+    class Buffer implements Closeable {
         private final JsonGenerator generator;
         private final SnippetOutputStream snippet;
+        private Runnable close;
 
         private Buffer() {
             this.snippet = new SnippetOutputStream(max);
             this.generator = generatorFactory.createGenerator(snippet);
+            this.close = () -> {
+                try {
+                    generator.close();
+                } finally {
+                    this.close = () -> {
+                    };
+                }
+            };
         }
 
         private void write(final JsonValue value) {
@@ -167,18 +175,14 @@
         }
 
         private String get() {
-            generator.close();
+            // If close is not called the string may be empty
+            close();
             return snippet.get();
         }
 
         @Override
         public void close() {
-            generator.close();
-        }
-
-        @Override
-        public void flush() {
-            generator.flush();
+            close.run();
         }
     }
 
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
index e841125..8b9be38 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
@@ -126,6 +126,10 @@
         }
     }
 
+    public void setSnippetMaxLength(final int value) {
+        builder.setSnippetMaxLength(value);
+    }
+
     public void setFailOnUnknownProperties(final boolean active) {
         builder.setFailOnUnknownProperties(active);
     }
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index c068809..5afe718 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -234,6 +234,12 @@
                                 .orElse(false)));
         builder.setAccessMode(accessMode);
 
+        config.getProperty("johnzon.snippetMaxLength")
+                .map(it -> Number.class.isInstance(it)?
+                        Number.class.cast(it).intValue() :
+                        Integer.parseInt(it.toString()))
+                .ifPresent(builder::setSnippetMaxLength);
+
         // user adapters
         config.getProperty(JsonbConfig.ADAPTERS).ifPresent(adapters -> Stream.of(JsonbAdapter[].class.cast(adapters)).forEach(adapter -> {
             final ParameterizedType pt = ParameterizedType.class.cast(
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
new file mode 100644
index 0000000..9edb94f
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/SnippetMaxLengthTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests that johnzon.snippetMaxLength works as expected
+ */
+public class SnippetMaxLengthTest {
+
+    @Test
+    public void testDefault() throws Exception {
+        try (final Jsonb jsonb = JsonbBuilder.create()) {
+            final String s = "{ \"name\" : { \"first\":\"Charlie\", \"last\": \"Brown\" }}";
+            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());
+        }
+    }
+
+    @Test
+    public void testDefaultTruncated() throws Exception {
+        try (final Jsonb jsonb = JsonbBuilder.create()) {
+            final String s = "{ \"name\" : { \"first\":\"Charlie\", \"last\": \"Brown\", \"age\": \"8.5\", \"dog\": \"Snoopy\" }}";
+            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());
+        }
+    }
+
+    @Test
+    public void testSetAsInt() throws Exception {
+        final JsonbConfig config = new JsonbConfig();
+        config.setProperty("johnzon.snippetMaxLength", 20);
+        try (final Jsonb jsonb = JsonbBuilder.create(config)) {
+            final String s = "{ \"name\" : { \"first\":\"Charlie\", \"last\": \"Brown\" }}";
+            jsonb.fromJson(s, Person.class);
+            fail();
+        } catch (JsonbException e) {
+            assertEquals("Can't map JSON Object to class java.lang.String: {\"first\":\"Charlie\",\"...", e.getMessage());
+        }
+    }
+
+
+    @Test
+    public void testSetAsString() throws Exception {
+        final JsonbConfig config = new JsonbConfig();
+        config.setProperty("johnzon.snippetMaxLength", "20");
+        try (final Jsonb jsonb = JsonbBuilder.create(config)) {
+            final String s = "{ \"name\" : { \"first\":\"Charlie\", \"last\": \"Brown\" }}";
+            jsonb.fromJson(s, Person.class);
+            fail();
+        } catch (JsonbException e) {
+            assertEquals("Can't map JSON Object to class java.lang.String: {\"first\":\"Charlie\",\"...", e.getMessage());
+        }
+    }
+
+    public static class Person {
+        private String name;
+
+        public Person() {
+        }
+
+        public Person(final String name) {
+            this.name = name;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(final String name) {
+            this.name = name;
+        }
+    }
+
+}