You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by jl...@apache.org on 2023/05/22 09:06:46 UTC

[johnzon] 04/11: feat(JOHNZON-397): make sure to pass the provider instance so we can configure the scale per provider

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

jlmonteiro pushed a commit to branch johnzon-1.2.x
in repository https://gitbox.apache.org/repos/asf/johnzon.git

commit 8e2b28157314b2b264be039371be24f1ca372cbb
Author: Jean-Louis Monteiro <jl...@tomitribe.com>
AuthorDate: Sat May 13 09:54:19 2023 +0200

    feat(JOHNZON-397): make sure to pass the provider instance so we can configure the scale per provider
---
 .../johnzon/core/CommentsJsonStreamParserImpl.java | 12 ++---
 .../apache/johnzon/core/JohnzonJsonParserImpl.java | 15 ++++--
 .../apache/johnzon/core/JsonArrayBuilderImpl.java  | 25 +++++-----
 .../johnzon/core/JsonBuilderFactoryImpl.java       | 16 +++---
 .../apache/johnzon/core/JsonInMemoryParser.java    |  8 ++-
 .../apache/johnzon/core/JsonMergePatchDiff.java    |  9 ++--
 .../apache/johnzon/core/JsonMergePatchImpl.java    |  9 ++--
 .../org/apache/johnzon/core/JsonNumberImpl.java    | 26 +++-------
 .../apache/johnzon/core/JsonObjectBuilderImpl.java | 19 +++++---
 .../apache/johnzon/core/JsonParserFactoryImpl.java | 20 ++++----
 .../org/apache/johnzon/core/JsonProviderImpl.java  | 57 +++++++++++++---------
 .../apache/johnzon/core/JsonReaderFactoryImpl.java | 14 +++---
 .../org/apache/johnzon/core/JsonReaderImpl.java    | 26 +++++-----
 .../apache/johnzon/core/JsonStreamParserImpl.java  | 15 +++---
 .../org/apache/johnzon/core/JsonNumberTest.java    |  6 +--
 .../johnzon/core/JsonParserStreamingTest.java      |  3 +-
 .../org/apache/johnzon/core/JsonParserTest.java    |  6 +--
 .../johnzon/core/JsonStreamParserImplTest.java     |  8 +--
 .../org/apache/johnzon/core/SerializationTest.java |  3 +-
 .../org/apache/johnzon/jsonb/JohnzonBuilder.java   | 12 ++---
 .../apache/johnzon/mapper/MapperConfigTest.java    |  2 +-
 .../test/java/org/superbiz/ExtendMappingTest.java  |  4 +-
 22 files changed, 171 insertions(+), 144 deletions(-)

diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java
index f9d298e6..fb199bda 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/CommentsJsonStreamParserImpl.java
@@ -27,8 +27,8 @@ public class CommentsJsonStreamParserImpl extends JsonStreamParserImpl {
                                         final int maxStringLength,
                                         final BufferStrategy.BufferProvider<char[]> bufferProvider,
                                         final BufferStrategy.BufferProvider<char[]> valueBuffer,
-                                        final boolean autoAdjust) {
-        super(inputStream, maxStringLength, bufferProvider, valueBuffer, autoAdjust);
+                                        final boolean autoAdjust, final JsonProviderImpl provider) {
+        super(inputStream, maxStringLength, bufferProvider, valueBuffer, autoAdjust, provider);
     }
 
     public CommentsJsonStreamParserImpl(final InputStream inputStream,
@@ -36,16 +36,16 @@ public class CommentsJsonStreamParserImpl extends JsonStreamParserImpl {
                                         final int maxStringLength,
                                         final BufferStrategy.BufferProvider<char[]> bufferProvider,
                                         final BufferStrategy.BufferProvider<char[]> valueBuffer,
-                                        final boolean autoAdjust) {
-        super(inputStream, encoding, maxStringLength, bufferProvider, valueBuffer, autoAdjust);
+                                        final boolean autoAdjust, final JsonProviderImpl provider) {
+        super(inputStream, encoding, maxStringLength, bufferProvider, valueBuffer, autoAdjust, provider);
     }
 
     public CommentsJsonStreamParserImpl(final Reader reader,
                                         final int maxStringLength,
                                         final BufferStrategy.BufferProvider<char[]> bufferProvider,
                                         final BufferStrategy.BufferProvider<char[]> valueBuffer,
-                                        final boolean autoAdjust) {
-        super(reader, maxStringLength, bufferProvider, valueBuffer, autoAdjust);
+                                        final boolean autoAdjust, final JsonProviderImpl provider) {
+        super(reader, maxStringLength, bufferProvider, valueBuffer, autoAdjust, provider);
     }
 
     @Override
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java
index 61cb7080..16d26400 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java
@@ -50,6 +50,13 @@ public abstract class JohnzonJsonParserImpl implements JohnzonJsonParser {
 
     private boolean manualNext = false;
 
+    private final JsonProviderImpl provider;
+
+    protected JohnzonJsonParserImpl(final JsonProviderImpl provider) {
+        this.provider = provider;
+    }
+
+
     @Override
     public Event next() {
         manualNext = true;
@@ -65,7 +72,7 @@ public abstract class JohnzonJsonParserImpl implements JohnzonJsonParser {
             throw new IllegalStateException(current + " doesn't support getObject()");
         }
 
-        JsonReaderImpl jsonReader = new JsonReaderImpl(this, true, getCharArrayProvider(), RejectDuplicateKeysMode.DEFAULT);
+        JsonReaderImpl jsonReader = new JsonReaderImpl(this, true, getCharArrayProvider(), RejectDuplicateKeysMode.DEFAULT, provider);
         return jsonReader.readObject();
     }
 
@@ -77,7 +84,7 @@ public abstract class JohnzonJsonParserImpl implements JohnzonJsonParser {
             throw new IllegalStateException(current + " doesn't support getArray()");
         }
 
-        JsonReaderImpl jsonReader = new JsonReaderImpl(this, true, getCharArrayProvider(), RejectDuplicateKeysMode.DEFAULT);
+        JsonReaderImpl jsonReader = new JsonReaderImpl(this, true, getCharArrayProvider(), RejectDuplicateKeysMode.DEFAULT, provider);
         return jsonReader.readArray();
     }
 
@@ -87,7 +94,7 @@ public abstract class JohnzonJsonParserImpl implements JohnzonJsonParser {
         switch (current) {
             case START_ARRAY:
             case START_OBJECT:
-                JsonReaderImpl jsonReader = new JsonReaderImpl(this, true, getCharArrayProvider(), RejectDuplicateKeysMode.DEFAULT);
+                JsonReaderImpl jsonReader = new JsonReaderImpl(this, true, getCharArrayProvider(), RejectDuplicateKeysMode.DEFAULT, provider);
                 return jsonReader.readValue();
             case VALUE_TRUE:
                 return JsonValue.TRUE;
@@ -102,7 +109,7 @@ public abstract class JohnzonJsonParserImpl implements JohnzonJsonParser {
                 if (isFitLong()) {
                     return new JsonLongImpl(getLong());
                 }
-                return new JsonNumberImpl(getBigDecimal());
+                return new JsonNumberImpl(getBigDecimal(), provider::checkBigDecimalScale);
             default:
                 throw new IllegalStateException(current + " doesn't support getValue()");
         }
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
index 1ee44fcd..87c9a161 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
@@ -36,6 +36,7 @@ import org.apache.johnzon.core.util.ArrayUtil;
 
 class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
     private RejectDuplicateKeysMode rejectDuplicateKeysMode;
+    private JsonProviderImpl jsonProvider;
     private List<JsonValue> tmpList;
     private BufferStrategy.BufferProvider<char[]> bufferProvider;
 
@@ -45,14 +46,15 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
 
     public JsonArrayBuilderImpl(final JsonArray initialData,
                                 final BufferStrategy.BufferProvider<char[]> provider,
-                                final RejectDuplicateKeysMode rejectDuplicateKeysMode) {
+                                final RejectDuplicateKeysMode rejectDuplicateKeysMode, final JsonProviderImpl jsonProvider) {
         this.tmpList = new ArrayList<>(initialData);
         this.bufferProvider = provider;
         this.rejectDuplicateKeysMode = rejectDuplicateKeysMode;
+        this.jsonProvider = jsonProvider;
     }
 
     public JsonArrayBuilderImpl(final Collection<?> initialData, final BufferStrategy.BufferProvider<char[]> provider,
-                                final RejectDuplicateKeysMode rejectDuplicateKeysMode) {
+                                final RejectDuplicateKeysMode rejectDuplicateKeysMode, final JsonProviderImpl jsonProvider) {
         this.bufferProvider = provider;
         this.rejectDuplicateKeysMode = rejectDuplicateKeysMode;
         this.tmpList = new ArrayList<>();
@@ -61,6 +63,7 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
                 add(initialValue);
             }
         }
+        this.jsonProvider = jsonProvider;
     }
 
     @Override
@@ -83,13 +86,13 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
 
     @Override
     public JsonArrayBuilder add(final int index, final BigDecimal value) {
-        addValue(index, new JsonNumberImpl(value));
+        addValue(index, new JsonNumberImpl(value, jsonProvider::checkBigDecimalScale));
         return this;
     }
 
     @Override
     public JsonArrayBuilder add(final int index, final BigInteger value) {
-        addValue(index, new JsonNumberImpl(new BigDecimal(value)));
+        addValue(index, new JsonNumberImpl(new BigDecimal(value), jsonProvider::checkBigDecimalScale));
         return this;
     }
 
@@ -149,13 +152,13 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
 
     @Override
     public JsonArrayBuilder set(final int index, final BigDecimal value) {
-        setValue(index, new JsonNumberImpl(value));
+        setValue(index, new JsonNumberImpl(value, jsonProvider::checkBigDecimalScale));
         return this;
     }
 
     @Override
     public JsonArrayBuilder set(final int index, final BigInteger value) {
-        setValue(index, new JsonNumberImpl(new BigDecimal(value)));
+        setValue(index, new JsonNumberImpl(new BigDecimal(value), jsonProvider::checkBigDecimalScale));
         return this;
     }
 
@@ -225,12 +228,12 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
         } else if (value instanceof String) {
             add((String) value);
         } else if (value instanceof Map) {
-            add(new JsonObjectBuilderImpl(Map.class.cast(value), bufferProvider, rejectDuplicateKeysMode).build());
+            add(new JsonObjectBuilderImpl(Map.class.cast(value), bufferProvider, rejectDuplicateKeysMode, jsonProvider).build());
         } else if (value instanceof Collection) {
-            add(new JsonArrayBuilderImpl(Collection.class.cast(value), bufferProvider, rejectDuplicateKeysMode).build());
+            add(new JsonArrayBuilderImpl(Collection.class.cast(value), bufferProvider, rejectDuplicateKeysMode, jsonProvider).build());
         } else if (value.getClass().isArray()) {
             final Collection<Object> collection = ArrayUtil.newCollection(value);
-            add(new JsonArrayBuilderImpl(collection, bufferProvider, rejectDuplicateKeysMode).build());
+            add(new JsonArrayBuilderImpl(collection, bufferProvider, rejectDuplicateKeysMode, jsonProvider).build());
         } else {
             throw new JsonException("Illegal JSON type! type=" + value.getClass());
         }
@@ -252,13 +255,13 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
 
     @Override
     public JsonArrayBuilder add(final BigDecimal value) {
-        addValue(new JsonNumberImpl(value));
+        addValue(new JsonNumberImpl(value, jsonProvider::checkBigDecimalScale));
         return this;
     }
 
     @Override
     public JsonArrayBuilder add(final BigInteger value) {
-        addValue(new JsonNumberImpl(new BigDecimal(value)));
+        addValue(new JsonNumberImpl(new BigDecimal(value), jsonProvider::checkBigDecimalScale));
         return this;
     }
 
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
index efd10fe6..99ec7e2d 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
@@ -37,6 +37,7 @@ import static java.util.Collections.emptyMap;
 class JsonBuilderFactoryImpl implements JsonBuilderFactory, Serializable {
     private final Map<String, Object> internalConfig = new HashMap<String, Object>();
     private RejectDuplicateKeysMode rejectDuplicateKeysMode;
+    private JsonProviderImpl provider;
     private BufferStrategy.BufferProvider<char[]> bufferProvider;
     private static final List<String> SUPPORTED_CONFIG_KEYS = RejectDuplicateKeysMode.CONFIG_KEYS;
 
@@ -45,9 +46,10 @@ class JsonBuilderFactoryImpl implements JsonBuilderFactory, Serializable {
     }
 
     JsonBuilderFactoryImpl(final Map<String, ?> config, final BufferStrategy.BufferProvider<char[]> bufferProvider,
-                           final RejectDuplicateKeysMode rejectDuplicateKeysMode) {
+                           final RejectDuplicateKeysMode rejectDuplicateKeysMode, final JsonProviderImpl provider) {
         this.bufferProvider = bufferProvider;
         this.rejectDuplicateKeysMode = rejectDuplicateKeysMode;
+        this.provider = provider;
         if (config != null && !config.isEmpty()) {
             for (String configKey : config.keySet()) {
                 if(SUPPORTED_CONFIG_KEYS.contains(configKey)) {
@@ -62,28 +64,28 @@ class JsonBuilderFactoryImpl implements JsonBuilderFactory, Serializable {
 
     @Override
     public JsonObjectBuilder createObjectBuilder() {
-        return new JsonObjectBuilderImpl(emptyMap(), bufferProvider, rejectDuplicateKeysMode);
+        return new JsonObjectBuilderImpl(emptyMap(), bufferProvider, rejectDuplicateKeysMode, provider);
     }
 
     @Override
     public JsonObjectBuilder createObjectBuilder(JsonObject initialData) {
-        return new JsonObjectBuilderImpl(initialData, bufferProvider, rejectDuplicateKeysMode);
+        return new JsonObjectBuilderImpl(initialData, bufferProvider, rejectDuplicateKeysMode, provider);
     }
 
     @Override
     public JsonArrayBuilder createArrayBuilder() {
-        return new JsonArrayBuilderImpl(emptyList(), bufferProvider, rejectDuplicateKeysMode);
+        return new JsonArrayBuilderImpl(emptyList(), bufferProvider, rejectDuplicateKeysMode, provider);
     }
 
 
     @Override
     public JsonArrayBuilder createArrayBuilder(JsonArray initialData) {
-        return new JsonArrayBuilderImpl(initialData, bufferProvider, rejectDuplicateKeysMode);
+        return new JsonArrayBuilderImpl(initialData, bufferProvider, rejectDuplicateKeysMode, provider);
     }
 
     @Override
     public JsonArrayBuilder createArrayBuilder(Collection<?> initialData) {
-        return new JsonArrayBuilderImpl(initialData, bufferProvider, rejectDuplicateKeysMode);
+        return new JsonArrayBuilderImpl(initialData, bufferProvider, rejectDuplicateKeysMode, provider);
     }
 
     @Override
@@ -93,7 +95,7 @@ class JsonBuilderFactoryImpl implements JsonBuilderFactory, Serializable {
 
     @Override
     public JsonObjectBuilder createObjectBuilder(Map<String, Object> initialValues) {
-        return new JsonObjectBuilderImpl(initialValues, bufferProvider, rejectDuplicateKeysMode);
+        return new JsonObjectBuilderImpl(initialValues, bufferProvider, rejectDuplicateKeysMode, provider);
     }
 
 }
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java
index 740a1007..e7f99560 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java
@@ -216,12 +216,16 @@ class JsonInMemoryParser extends JohnzonJsonParserImpl {
 
     }
 
-    JsonInMemoryParser(final JsonObject object, final BufferStrategy.BufferProvider<char[]> bufferProvider) {
+    JsonInMemoryParser(final JsonObject object, final BufferStrategy.BufferProvider<char[]> bufferProvider,
+                      final JsonProviderImpl provider) {
+        super(provider);
         stack.push(new ObjectIterator(object));
         this.bufferProvider = bufferProvider;
     }
 
-    JsonInMemoryParser(final JsonArray array, final BufferStrategy.BufferProvider<char[]> bufferProvider) {
+    JsonInMemoryParser(final JsonArray array, final BufferStrategy.BufferProvider<char[]> bufferProvider,
+                       final JsonProviderImpl provider) {
+        super(provider);
         stack.push(new ArrayIterator(array));
         this.bufferProvider = bufferProvider;
     }
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchDiff.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchDiff.java
index 3825229b..e137e90d 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchDiff.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchDiff.java
@@ -32,20 +32,23 @@ class JsonMergePatchDiff extends DiffBase {
     private final BufferStrategy.BufferProvider<char[]> bufferProvider;
     private final JsonValue source;
     private final JsonValue target;
+    private JsonProviderImpl provider;
 
     public JsonMergePatchDiff(final JsonValue source, final JsonValue target,
-                              final BufferStrategy.BufferProvider<char[]> bufferProvider) {
+                              final BufferStrategy.BufferProvider<char[]> bufferProvider,
+                              final JsonProviderImpl provider) {
         this.bufferProvider = bufferProvider;
         this.source = source;
         this.target = target;
+        this.provider = provider;
     }
 
     public JsonMergePatch calculateDiff() {
-        return new JsonMergePatchImpl(diff(source, target), bufferProvider);
+        return new JsonMergePatchImpl(diff(source, target), bufferProvider, provider);
     }
 
     private JsonValue diff(JsonValue source, JsonValue target) {
-        JsonObjectBuilder builder = new JsonObjectBuilderImpl(emptyMap(), bufferProvider, RejectDuplicateKeysMode.DEFAULT);
+        JsonObjectBuilder builder = new JsonObjectBuilderImpl(emptyMap(), bufferProvider, RejectDuplicateKeysMode.DEFAULT, provider);
 
         if (isJsonObject(source) && isJsonObject(target)) {
             JsonObject srcObj = source.asJsonObject();
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java
index 9d40f052..2773191a 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java
@@ -31,10 +31,13 @@ import javax.json.JsonValue;
 public class JsonMergePatchImpl implements JsonMergePatch, Serializable {
     private JsonValue patch;
     private BufferStrategy.BufferProvider<char[]> bufferProvider;
+    private JsonProviderImpl provider;
 
-    public JsonMergePatchImpl(final JsonValue patch, final BufferStrategy.BufferProvider<char[]> bufferProvider) {
+    public JsonMergePatchImpl(final JsonValue patch, final BufferStrategy.BufferProvider<char[]> bufferProvider,
+                              final JsonProviderImpl provider) {
         this.patch = patch;
         this.bufferProvider = bufferProvider;
+        this.provider = provider;
     }
 
     @Override
@@ -51,14 +54,14 @@ public class JsonMergePatchImpl implements JsonMergePatch, Serializable {
 
             return applyJsonObjectPatch(valueToApplyPatchOn.asJsonObject(), patchObject);
         } else {
-            // this must be a native JsonValue or JsonObject, so we just replace the
+            // this must be a native JsonValue or JsonObject, so we just replace
             // the whole original valueToApplyPatchOn with the new jsonValue
             return patch;
         }
     }
 
     private JsonValue applyJsonObjectPatch(JsonObject jsonObject, JsonObject patch) {
-        JsonObjectBuilder builder = new JsonObjectBuilderImpl(jsonObject, bufferProvider, RejectDuplicateKeysMode.DEFAULT);
+        JsonObjectBuilder builder = new JsonObjectBuilderImpl(jsonObject, bufferProvider, RejectDuplicateKeysMode.DEFAULT, provider);
 
         for (Map.Entry<String, JsonValue> patchAttrib : patch.entrySet()) {
             String attribName = patchAttrib.getKey();
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
index 57db2ca1..d63fa34f 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonNumberImpl.java
@@ -22,13 +22,15 @@ import javax.json.JsonNumber;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.util.function.Consumer;
 
 final class JsonNumberImpl implements JsonNumber, Serializable {
     private final BigDecimal value;
     private transient Integer hashCode = null;
-    private static final int MAX_BIG_DECIMAL_SCALE = toInt(System.getProperty("johnzon.max-big-decimal-scale", "1000"));
+    private transient Consumer<BigDecimal> maxBigDecimalScale = (bigDecimal) -> {}; // for deserialization?
 
-    JsonNumberImpl(final BigDecimal decimal) {
+    JsonNumberImpl(final BigDecimal decimal, final Consumer<BigDecimal> maxBigDecimalScale) {
+        this.maxBigDecimalScale = maxBigDecimalScale;
         if (decimal == null) {
             throw new NullPointerException("decimal must not be null");
         }
@@ -70,13 +72,13 @@ final class JsonNumberImpl implements JsonNumber, Serializable {
 
     @Override
     public BigInteger bigIntegerValue() {
-        checkBigDecimalScale();
+        maxBigDecimalScale.accept(value);
         return value.toBigInteger();
     }
 
     @Override
     public BigInteger bigIntegerValueExact() {
-        checkBigDecimalScale();
+        maxBigDecimalScale.accept(value);
         return value.toBigIntegerExact();
     }
 
@@ -121,20 +123,4 @@ final class JsonNumberImpl implements JsonNumber, Serializable {
         }
     }
 
-    private void checkBigDecimalScale() {
-        // should be fine enough. Maybe we should externalize so users can pick something better if they need to
-        // it becomes their responsibility to fix the limit and may expose them to a DoS attack
-        final int limit = MAX_BIG_DECIMAL_SCALE;
-        final int absScale = Math.abs(value.scale());
-
-        if (absScale > limit) {
-            throw new ArithmeticException(String.format(
-                "BigDecimal scale (%d) limit exceeds maximum allowed (%d)",
-                value.scale(), limit));
-        }
-    }
-
-    private static Integer toInt(final Object v) {
-        return !Integer.class.isInstance(v) ? Integer.parseInt(v.toString()) : Integer.class.cast(v);
-    }
 }
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
index 2eb4ab09..33ef91d3 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
@@ -37,6 +37,7 @@ import org.apache.johnzon.core.util.ArrayUtil;
 
 class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
     private RejectDuplicateKeysMode rejectDuplicateKeysMode;
+    private JsonProviderImpl provider;
     private BufferStrategy.BufferProvider<char[]> bufferProvider;
     private Map<String, JsonValue> attributeMap = new LinkedHashMap<>();
 
@@ -46,17 +47,21 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
 
     public JsonObjectBuilderImpl(final JsonObject initialData,
                                  final BufferStrategy.BufferProvider<char[]> bufferProvider,
-                                 final RejectDuplicateKeysMode rejectDuplicateKeysMode) {
+                                 final RejectDuplicateKeysMode rejectDuplicateKeysMode,
+                                 final JsonProviderImpl provider) {
         this.bufferProvider = bufferProvider;
         this.rejectDuplicateKeysMode = rejectDuplicateKeysMode;
+        this.provider = provider;
         this.attributeMap = new LinkedHashMap<>(initialData);
     }
 
     public JsonObjectBuilderImpl(final Map<String, Object> initialValues,
                                  final BufferStrategy.BufferProvider<char[]> bufferProvider,
-                                 final RejectDuplicateKeysMode rejectDuplicateKeysMode) {
+                                 final RejectDuplicateKeysMode rejectDuplicateKeysMode,
+                                 final JsonProviderImpl provider) {
         this.bufferProvider = bufferProvider;
         this.rejectDuplicateKeysMode = rejectDuplicateKeysMode;
+        this.provider = provider;
         if (!initialValues.isEmpty()) {
             for (Map.Entry<String, Object> entry : initialValues.entrySet()) {
                 add(entry.getKey(), entry.getValue());
@@ -88,12 +93,12 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
         } else if (value == null) {
             addNull(name);
         } else if (value instanceof Map) {
-            add(name, new JsonObjectBuilderImpl(Map.class.cast(value), bufferProvider, rejectDuplicateKeysMode).build());
+            add(name, new JsonObjectBuilderImpl(Map.class.cast(value), bufferProvider, rejectDuplicateKeysMode, provider).build());
         } else if (value instanceof Collection) {
-            add(name, new JsonArrayBuilderImpl(Collection.class.cast(value), bufferProvider, rejectDuplicateKeysMode).build());
+            add(name, new JsonArrayBuilderImpl(Collection.class.cast(value), bufferProvider, rejectDuplicateKeysMode, provider).build());
         } else if (value.getClass().isArray()) {
             final Collection<Object> collection = ArrayUtil.newCollection(value);
-            add(name, new JsonArrayBuilderImpl(collection, bufferProvider, rejectDuplicateKeysMode).build());
+            add(name, new JsonArrayBuilderImpl(collection, bufferProvider, rejectDuplicateKeysMode, provider).build());
         } else {
             throw new JsonException("Illegal JSON type! name=" + name + " type=" + value.getClass());
         }
@@ -113,13 +118,13 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
 
     @Override
     public JsonObjectBuilder add(final String name, final BigInteger value) {
-        putValue(name, new JsonNumberImpl(new BigDecimal(value)));
+        putValue(name, new JsonNumberImpl(new BigDecimal(value), provider::checkBigDecimalScale));
         return this;
     }
 
     @Override
     public JsonObjectBuilder add(final String name, final BigDecimal value) {
-        putValue(name, new JsonNumberImpl(value));
+        putValue(name, new JsonNumberImpl(value, provider::checkBigDecimalScale));
         return this;
     }
 
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
index 85174bce..841d0a37 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonParserFactoryImpl.java
@@ -53,9 +53,11 @@ public class JsonParserFactoryImpl extends AbstractJsonFactory implements JsonPa
     private final boolean supportsComments;
     private final boolean autoAdjustBuffers;
     private final Charset defaultEncoding;
+    private final JsonProviderImpl provider;
 
-    JsonParserFactoryImpl(final Map<String, ?> config) {
+    JsonParserFactoryImpl(final Map<String, ?> config, final JsonProviderImpl provider) {
         super(config, SUPPORTED_CONFIG_KEYS, null);
+        this.provider = provider;
 
         final int bufferSize = getInt(BUFFER_LENGTH, DEFAULT_BUFFER_LENGTH);
         if (bufferSize <= 0) {
@@ -79,26 +81,26 @@ public class JsonParserFactoryImpl extends AbstractJsonFactory implements JsonPa
             return getDefaultJsonParserImpl(in, defaultEncoding);
         }
         if (supportsComments) {
-            return new CommentsJsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers);
+            return new CommentsJsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers, provider);
         }
         //UTF Auto detection RFC 4627
-        return new JsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers);
+        return new JsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers, provider);
     }
 
     private JsonStreamParserImpl getDefaultJsonParserImpl(final InputStream in, final Charset charset) {
         if (supportsComments) {
-            return new CommentsJsonStreamParserImpl(in, charset, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers);
+            return new CommentsJsonStreamParserImpl(in, charset, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers, provider);
         }
         //use provided charset
-        return new JsonStreamParserImpl(in, charset, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers);
+        return new JsonStreamParserImpl(in, charset, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers, provider);
     }
 
     private JsonStreamParserImpl getDefaultJsonParserImpl(final Reader in) {
         if (supportsComments) {
-            return new CommentsJsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers);
+            return new CommentsJsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers, provider);
         }
         //no charset necessary
-        return new JsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers);
+        return new JsonStreamParserImpl(in, maxSize, bufferProvider, valueBufferProvider, autoAdjustBuffers, provider);
     }
 
     @Override
@@ -119,13 +121,13 @@ public class JsonParserFactoryImpl extends AbstractJsonFactory implements JsonPa
     @Override
     public JsonParser createParser(final JsonObject obj) {
         // no need of a comment version since JsonObject has no comment event
-        return new JsonInMemoryParser(obj, bufferProvider);
+        return new JsonInMemoryParser(obj, bufferProvider, provider);
     }
 
     @Override
     public JsonParser createParser(final JsonArray array) {
         // no need of a comment version since JsonObject has no comment event
-        return new JsonInMemoryParser(array, bufferProvider);
+        return new JsonInMemoryParser(array, bufferProvider, provider);
     }
 
     @Override
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
index 1bfcd716..55101a32 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.johnzon.core;
 
-import org.apache.johnzon.core.spi.JsonPointerFactory;
-
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Reader;
@@ -29,9 +27,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collection;
 import java.util.Map;
-import java.util.ServiceLoader;
 import java.util.function.Supplier;
-import java.util.stream.StreamSupport;
 
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
@@ -56,26 +52,18 @@ import javax.json.stream.JsonGeneratorFactory;
 import javax.json.stream.JsonParser;
 import javax.json.stream.JsonParserFactory;
 
-import static java.util.Comparator.comparing;
-
 public class JsonProviderImpl extends JsonProvider implements Serializable {
     private final Supplier<BufferStrategy.BufferProvider<char[]>> bufferProvider = new Cached<>(() ->
         BufferStrategyFactory.valueOf(System.getProperty(AbstractJsonFactory.BUFFER_STRATEGY, "QUEUE"))
             .newCharProvider(Integer.getInteger("org.apache.johnzon.default-char-provider.length", 1024)));
 
-    private final JsonReaderFactory readerFactory = new JsonReaderFactoryImpl(null);
-    private final JsonParserFactory parserFactory = new JsonParserFactoryImpl(null);
+    private final JsonReaderFactory readerFactory = new JsonReaderFactoryImpl(null, this);
+    private final JsonParserFactory parserFactory = new JsonParserFactoryImpl(null, this);
     private final JsonGeneratorFactory generatorFactory = new JsonGeneratorFactoryImpl(null);
     private final JsonWriterFactory writerFactory = new JsonWriterFactoryImpl(null);
     private final Supplier<JsonBuilderFactory> builderFactory = new Cached<>(() ->
-            new JsonBuilderFactoryImpl(null, bufferProvider.get(), RejectDuplicateKeysMode.DEFAULT));
-    private final JsonPointerFactory jsonPointerFactory;
-
-    public JsonProviderImpl() {
-        jsonPointerFactory = StreamSupport.stream(ServiceLoader.load(JsonPointerFactory.class).spliterator(), false)
-                .min(comparing(JsonPointerFactory::ordinal))
-                .orElseGet(DefaultJsonPointerFactory::new);
-    }
+            new JsonBuilderFactoryImpl(null, bufferProvider.get(), RejectDuplicateKeysMode.DEFAULT, this));
+    private int maxBigDecimalScale = Integer.getInteger("johnzon.max-big-decimal-scale", 1_000);
 
     @Override
     public JsonParser createParser(final InputStream in) {
@@ -99,12 +87,12 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
 
     @Override
     public JsonParserFactory createParserFactory(final Map<String, ?> config) {
-        return (config == null || config.isEmpty()) ? parserFactory : new JsonParserFactoryImpl(config);
+        return (config == null || config.isEmpty()) ? parserFactory : new JsonParserFactoryImpl(config, this);
     }
 
     @Override
     public JsonReaderFactory createReaderFactory(final Map<String, ?> config) {
-        return (config == null || config.isEmpty()) ? readerFactory : new JsonReaderFactoryImpl(config);
+        return (config == null || config.isEmpty()) ? readerFactory : new JsonReaderFactoryImpl(config, this);
     }
 
     @Override
@@ -189,19 +177,19 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
 
     @Override
     public JsonNumber createValue(final BigDecimal value) {
-        return new JsonNumberImpl(value);
+        return new JsonNumberImpl(value, this::checkBigDecimalScale);
     }
 
     @Override
     public JsonNumber createValue(final BigInteger value) {
-        return new JsonNumberImpl(new BigDecimal(value.toString()));
+        return new JsonNumberImpl(new BigDecimal(value.toString()), this::checkBigDecimalScale);
     }
 
     @Override
     public JsonBuilderFactory createBuilderFactory(final Map<String, ?> config) {
         final JsonBuilderFactory builderFactory = this.builderFactory.get();
         return (config == null || config.isEmpty()) ?
-                builderFactory : new JsonBuilderFactoryImpl(config, bufferProvider.get(), RejectDuplicateKeysMode.from(config));
+                builderFactory : new JsonBuilderFactoryImpl(config, bufferProvider.get(), RejectDuplicateKeysMode.from(config), this);
     }
 
     @Override
@@ -216,7 +204,7 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
 
     @Override
     public JsonPointer createPointer(String path) {
-        return jsonPointerFactory.createPointer(this, path);
+        return new JsonPointerImpl(this, path);
     }
 
     @Override
@@ -231,12 +219,20 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
 
     @Override
     public JsonMergePatch createMergePatch(JsonValue patch) {
-        return new JsonMergePatchImpl(patch, bufferProvider.get());
+        return new JsonMergePatchImpl(patch, bufferProvider.get(), this);
     }
 
     @Override
     public JsonMergePatch createMergeDiff(JsonValue source, JsonValue target) {
-        return new JsonMergePatchDiff(source, target, bufferProvider.get()).calculateDiff();
+        return new JsonMergePatchDiff(source, target, bufferProvider.get(), this).calculateDiff();
+    }
+
+    public int getMaxBigDecimalScale() {
+        return maxBigDecimalScale;
+    }
+
+    public void setMaxBigDecimalScale(final int maxBigDecimalScale) {
+        this.maxBigDecimalScale = maxBigDecimalScale;
     }
 
     /**
@@ -263,4 +259,17 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
             return computed;
         }
     }
+
+    public void checkBigDecimalScale(final BigDecimal value) {
+        // should be fine enough. Maybe we should externalize so users can pick something better if they need to
+        // it becomes their responsibility to fix the limit and may expose them to a DoS attack
+        final int limit = maxBigDecimalScale;
+        final int absScale = Math.abs(value.scale());
+
+        if (absScale > limit) {
+            throw new ArithmeticException(String.format(
+                "BigDecimal scale (%d) limit exceeds maximum allowed (%d)",
+                value.scale(), limit));
+        }
+    }
 }
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderFactoryImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderFactoryImpl.java
index 233f8b02..1608e496 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderFactoryImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderFactoryImpl.java
@@ -34,33 +34,35 @@ class JsonReaderFactoryImpl extends AbstractJsonFactory implements JsonReaderFac
 
     private final JsonParserFactoryImpl parserFactory;
     private final RejectDuplicateKeysMode rejectDuplicateKeys;
+    private JsonProviderImpl provider;
 
-    JsonReaderFactoryImpl(final Map<String, ?> config) {
+    JsonReaderFactoryImpl(final Map<String, ?> config, final JsonProviderImpl provider) {
         super(config, SUPPORTED_CONFIG_KEYS, JsonParserFactoryImpl.SUPPORTED_CONFIG_KEYS);
+        this.provider = provider;
         if (!internalConfig.isEmpty()) {
             RejectDuplicateKeysMode.CONFIG_KEYS.forEach(internalConfig::remove);
         }
-        this.parserFactory = new JsonParserFactoryImpl(internalConfig);
+        this.parserFactory = new JsonParserFactoryImpl(internalConfig, provider);
         this.rejectDuplicateKeys = RejectDuplicateKeysMode.from(config);
     }
 
     @Override
     public JsonReader createReader(final Reader reader) {
-        return new JsonReaderImpl(parserFactory.createInternalParser(reader), parserFactory.getValueBufferProvider(), rejectDuplicateKeys);
+        return new JsonReaderImpl(parserFactory.createInternalParser(reader), parserFactory.getValueBufferProvider(), rejectDuplicateKeys, provider);
     }
 
     @Override
     public JsonReader createReader(final InputStream in) {
-        return new JsonReaderImpl(parserFactory.createInternalParser(in), parserFactory.getValueBufferProvider(), rejectDuplicateKeys);
+        return new JsonReaderImpl(parserFactory.createInternalParser(in), parserFactory.getValueBufferProvider(), rejectDuplicateKeys, provider);
     }
 
     @Override
     public JsonReader createReader(final InputStream in, final Charset charset) {
-        return new JsonReaderImpl(parserFactory.createInternalParser(in, charset), parserFactory.getValueBufferProvider(), rejectDuplicateKeys);
+        return new JsonReaderImpl(parserFactory.createInternalParser(in, charset), parserFactory.getValueBufferProvider(), rejectDuplicateKeys, provider);
     }
 
     public JsonReader createReader(final JsonParser parser) {
-        return new JsonReaderImpl(parser, parserFactory.getValueBufferProvider(), rejectDuplicateKeys);
+        return new JsonReaderImpl(parser, parserFactory.getValueBufferProvider(), rejectDuplicateKeys, provider);
     }
 
     @Override
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java
index 969ad9a7..bdc48577 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java
@@ -36,14 +36,15 @@ import static java.util.Collections.emptyMap;
 public class JsonReaderImpl implements JsonReader {
     private final JohnzonJsonParser parser;
     private final BufferStrategy.BufferProvider<char[]> bufferProvider;
+    private JsonProviderImpl provider;
     private final RejectDuplicateKeysMode rejectDuplicateKeysMode;
     private boolean closed = false;
 
     private boolean subStreamReader;
 
     public JsonReaderImpl(final JsonParser parser, final BufferStrategy.BufferProvider<char[]> bufferProvider,
-                          final RejectDuplicateKeysMode rejectDuplicateKeysMode) {
-        this(parser, false, bufferProvider, rejectDuplicateKeysMode);
+                          final RejectDuplicateKeysMode rejectDuplicateKeysMode, final JsonProviderImpl provider) {
+        this(parser, false, bufferProvider, rejectDuplicateKeysMode, provider);
     }
 
     /**
@@ -54,8 +55,9 @@ public class JsonReaderImpl implements JsonReader {
      */
     public JsonReaderImpl(final JsonParser parser, boolean subStreamReader,
                           final BufferStrategy.BufferProvider<char[]> bufferProvider,
-                          final RejectDuplicateKeysMode rejectDuplicateKeys) {
+                          final RejectDuplicateKeysMode rejectDuplicateKeys, final JsonProviderImpl provider) {
         this.bufferProvider = bufferProvider;
+        this.provider = provider;
         if (parser instanceof JohnzonJsonParser) {
             this.parser = (JohnzonJsonParser) parser;
         } else {
@@ -89,14 +91,14 @@ public class JsonReaderImpl implements JsonReader {
 
         switch (next) {
             case START_OBJECT:
-                final JsonObjectBuilder objectBuilder = new JsonObjectBuilderImpl(emptyMap(), bufferProvider, rejectDuplicateKeysMode);
+                final JsonObjectBuilder objectBuilder = new JsonObjectBuilderImpl(emptyMap(), bufferProvider, rejectDuplicateKeysMode, provider);
                 parseObject(objectBuilder);
                 if (!subStreamReader && parser.hasNext()) {
                     throw new JsonParsingException("Expected end of file", parser.getLocation());
                 }
                 return objectBuilder.build();
             case START_ARRAY:
-                final JsonArrayBuilder arrayBuilder = new JsonArrayBuilderImpl(emptyList(), bufferProvider, rejectDuplicateKeysMode);
+                final JsonArrayBuilder arrayBuilder = new JsonArrayBuilderImpl(emptyList(), bufferProvider, rejectDuplicateKeysMode, provider);
                 parseArray(arrayBuilder);
                 if (!subStreamReader && parser.hasNext()) {
                     throw new JsonParsingException("Expected end of file", parser.getLocation());
@@ -128,7 +130,7 @@ public class JsonReaderImpl implements JsonReader {
                 if (parser.isFitLong()) {
                     number = new JsonLongImpl(parser.getLong());
                 } else {
-                    number = new JsonNumberImpl(parser.getBigDecimal());
+                    number = new JsonNumberImpl(parser.getBigDecimal(), provider::checkBigDecimalScale);
                 }
                 if (!subStreamReader && parser.hasNext()) {
                     throw new JsonParsingException("Expected end of file", parser.getLocation());
@@ -182,13 +184,13 @@ public class JsonReaderImpl implements JsonReader {
                     break;
 
                 case START_OBJECT:
-                    JsonObjectBuilder subObject = new JsonObjectBuilderImpl(emptyMap(), bufferProvider, rejectDuplicateKeysMode);
+                    JsonObjectBuilder subObject = new JsonObjectBuilderImpl(emptyMap(), bufferProvider, rejectDuplicateKeysMode, provider);
                     parseObject(subObject);
                     builder.add(key, subObject);
                     break;
 
                 case START_ARRAY:
-                    JsonArrayBuilder subArray = new JsonArrayBuilderImpl(emptyList(), bufferProvider, rejectDuplicateKeysMode);
+                    JsonArrayBuilder subArray = new JsonArrayBuilderImpl(emptyList(), bufferProvider, rejectDuplicateKeysMode, provider);
                     parseArray(subArray);
                     builder.add(key, subArray);
                     break;
@@ -197,7 +199,7 @@ public class JsonReaderImpl implements JsonReader {
                     if (parser.isIntegralNumber() && parser.isNotTooLong()) {
                         builder.add(key, new JsonLongImpl(parser.getLong()));
                     } else {
-                        builder.add(key, new JsonNumberImpl(parser.getBigDecimal()));
+                        builder.add(key, new JsonNumberImpl(parser.getBigDecimal(), provider::checkBigDecimalScale));
                     }
                     break;
 
@@ -237,19 +239,19 @@ public class JsonReaderImpl implements JsonReader {
                     if (parser.isFitLong()) {
                         builder.add(new JsonLongImpl(parser.getLong()));
                     } else {
-                        builder.add(new JsonNumberImpl(parser.getBigDecimal()));
+                        builder.add(new JsonNumberImpl(parser.getBigDecimal(), provider::checkBigDecimalScale));
                     }
                     break;
 
                 case START_OBJECT:
-                    JsonObjectBuilder subObject = new JsonObjectBuilderImpl(emptyMap(), bufferProvider, rejectDuplicateKeysMode);
+                    JsonObjectBuilder subObject = new JsonObjectBuilderImpl(emptyMap(), bufferProvider, rejectDuplicateKeysMode, provider);
                     parseObject(subObject);
                     builder.add(subObject);
                     break;
 
                 case START_ARRAY:
                     JsonArrayBuilder subArray = null;
-                    parseArray(subArray = new JsonArrayBuilderImpl(emptyList(), bufferProvider, rejectDuplicateKeysMode));
+                    parseArray(subArray = new JsonArrayBuilderImpl(emptyList(), bufferProvider, rejectDuplicateKeysMode, provider));
                     builder.add(subArray);
                     break;
 
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
index c854069d..7619ad8d 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java
@@ -118,29 +118,30 @@ public class JsonStreamParserImpl extends JohnzonJsonParserImpl implements JsonC
     //detect charset according to RFC 4627
     public JsonStreamParserImpl(final InputStream inputStream, final int maxStringLength,
                                 final BufferStrategy.BufferProvider<char[]> bufferProvider, final BufferStrategy.BufferProvider<char[]> valueBuffer,
-                                final boolean autoAdjust) {
+                                final boolean autoAdjust, final JsonProviderImpl provider) {
 
-        this(inputStream, null, null, maxStringLength, bufferProvider, valueBuffer, autoAdjust);
+        this(inputStream, null, null, maxStringLength, bufferProvider, valueBuffer, autoAdjust, provider);
     }
 
     //use charset provided
     public JsonStreamParserImpl(final InputStream inputStream, final Charset encoding, final int maxStringLength,
                                 final BufferStrategy.BufferProvider<char[]> bufferProvider, final BufferStrategy.BufferProvider<char[]> valueBuffer,
-                                final boolean autoAdjust) {
+                                final boolean autoAdjust, final JsonProviderImpl provider) {
 
-        this(inputStream, null, encoding, maxStringLength, bufferProvider, valueBuffer, autoAdjust);
+        this(inputStream, null, encoding, maxStringLength, bufferProvider, valueBuffer, autoAdjust, provider);
     }
 
     public JsonStreamParserImpl(final Reader reader, final int maxStringLength, final BufferStrategy.BufferProvider<char[]> bufferProvider,
-                                final BufferStrategy.BufferProvider<char[]> valueBuffer, final boolean autoAdjust) {
+                                final BufferStrategy.BufferProvider<char[]> valueBuffer, final boolean autoAdjust, final JsonProviderImpl provider) {
 
-        this(null, reader, null, maxStringLength, bufferProvider, valueBuffer, autoAdjust);
+        this(null, reader, null, maxStringLength, bufferProvider, valueBuffer, autoAdjust, provider);
     }
 
     private JsonStreamParserImpl(final InputStream inputStream, final Reader reader, final Charset encoding, final int maxStringLength,
                                  final BufferStrategy.BufferProvider<char[]> bufferProvider, final BufferStrategy.BufferProvider<char[]> valueBuffer,
-                                 final boolean autoAdjust) {
+                                 final boolean autoAdjust, final JsonProviderImpl provider) {
 
+        super(provider);
         this.autoAdjust = autoAdjust;
         this.maxValueLength = maxStringLength <= 0 ? 8192 : maxStringLength;
         this.fallBackCopyBuffer = valueBuffer.newBuffer();
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonNumberTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonNumberTest.java
index f77773b6..21ddd12e 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonNumberTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonNumberTest.java
@@ -77,7 +77,7 @@ public class JsonNumberTest {
     @Test
     public void testSlowBigIntegerConversion() {
         JsonArray array = Json.createArrayBuilder()
-                              .add(new BigDecimal("1000000000e1000"))
+                              .add(new BigDecimal("1e1000")) // 1e20000000 --> lost of damage
                               .add(Double.MAX_VALUE)
                               .build();
 
@@ -85,7 +85,7 @@ public class JsonNumberTest {
             long start = System.nanoTime();
             for (int i = 1; i < 5; i++) {
                 // if it takes a few seconds in any machine, that's already too much
-                if (TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) > (3 * i)) {
+                if (TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) > 1) {
                     fail("took too long: " + TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) + " s" +
                          " to compute " + i + " conversions toBigInteger");
                 }
@@ -101,7 +101,7 @@ public class JsonNumberTest {
             for (int i = 1; i < 100; i++) {
                 // if it takes a second in any machine, that's already too much
                 // depends on the allowed scale in JsonNumberImpl#checkBigDecimalScale
-                if (TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) > (30 * i)) {
+                if (TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) > 1) {
                     fail("took too long: " + TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start) + " s" +
                          " to compute " + i + " conversions toBigInteger");
                 }
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserStreamingTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserStreamingTest.java
index 42fd6594..b0639743 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserStreamingTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserStreamingTest.java
@@ -49,7 +49,8 @@ public class JsonParserStreamingTest {
 
         final BufferStrategy.BufferProvider<char[]> bs = BufferStrategyFactory.valueOf("QUEUE").newCharProvider(len);
         try (final InputStream stream = new ByteArrayInputStream(bytes);
-                final JsonStreamParserImpl impl = new JsonStreamParserImpl(stream, len, bs, bs, false)) {
+                final JsonStreamParserImpl impl = new JsonStreamParserImpl(stream, len, bs, bs, false,
+                                                               (JsonProviderImpl) JsonProviderImpl.provider())) {
 
             while (impl.hasNext()) {
                 impl.next();
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
index d388f5f4..41ebf148 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java
@@ -355,10 +355,10 @@ public class JsonParserTest {
     public void simpleInMemory() {
         final JsonObjectBuilder ob = Json.createObjectBuilder();
         ob.add("a", new JsonStringImpl("b"));
-        ob.add("c", new JsonNumberImpl(new BigDecimal(4)));
+        ob.add("c", new JsonNumberImpl(new BigDecimal(4), ((JsonProviderImpl)JsonProviderImpl.provider())::checkBigDecimalScale));
         JsonArrayBuilder ab = Json.createArrayBuilder();
-        ab.add(new JsonNumberImpl(new BigDecimal(1)));
-        ab.add(new JsonNumberImpl(new BigDecimal(-2)));
+        ab.add(new JsonNumberImpl(new BigDecimal(1), ((JsonProviderImpl)JsonProviderImpl.provider())::checkBigDecimalScale));
+        ab.add(new JsonNumberImpl(new BigDecimal(-2), ((JsonProviderImpl)JsonProviderImpl.provider())::checkBigDecimalScale));
         
         ob.add("d", ab);
         ob.add ("e", Json.createObjectBuilder()
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonStreamParserImplTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonStreamParserImplTest.java
index 45371389..f155d138 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonStreamParserImplTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonStreamParserImplTest.java
@@ -35,9 +35,9 @@ public class JsonStreamParserImplTest {
     @Test
     public void ensureNoArrayBoundErrorWhenOverflow() throws IOException {
         final String json = new JsonObjectBuilderImpl(
-                emptyMap(),
-                BufferStrategyFactory.valueOf("QUEUE").newCharProvider(100),
-                RejectDuplicateKeysMode.TRUE)
+            emptyMap(),
+            BufferStrategyFactory.valueOf("QUEUE").newCharProvider(100),
+            RejectDuplicateKeysMode.TRUE, (JsonProviderImpl) JsonProviderImpl.provider())
                 .add("content", "{\"foo\":\"barbar\\barbarbar\"}")
                 .build()
                 .toString();
@@ -46,7 +46,7 @@ public class JsonStreamParserImplTest {
                 10,
                 BufferStrategyFactory.valueOf("QUEUE").newCharProvider(10),
                 BufferStrategyFactory.valueOf("QUEUE").newCharProvider(10),
-                true);
+                true, (JsonProviderImpl) JsonProviderImpl.provider());
         final List<String> events = new ArrayList<>();
         while (parser.hasNext()) {
             final JsonParser.Event event = parser.next();
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java
index 6074563b..73699dfd 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/SerializationTest.java
@@ -52,7 +52,8 @@ public class SerializationTest {
 
     @Test
     public void jsonNumber() throws IOException, ClassNotFoundException {
-        final JsonNumber source = new JsonNumberImpl(new BigDecimal("1.0"));
+        final JsonNumber source = new JsonNumberImpl(new BigDecimal("1.0"),
+                                                     ((JsonProviderImpl) JsonProviderImpl.provider())::checkBigDecimalScale);
         final JsonNumber deserialized = serialDeser(source);
         assertNotSame(source, deserialized);
         assertEquals(1.0, deserialized.doubleValue(), 0.);
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 46f99177..3cab08e2 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
@@ -107,10 +107,8 @@ public class JohnzonBuilder implements JsonbBuilder {
         final boolean skipCdi = shouldSkipCdi();
 
         // todo: global spec toggle to disable all these ones at once?
-        builder.setUseBigDecimalForObjectNumbers(
-            config.getProperty("johnzon.use-big-decimal-for-object").map(this::toBool).orElse(true));
-        builder.setMaxBigDecimalScale(
-            config.getProperty("johnzon.max-big-decimal-scale").map(this::toInt).orElse(1000));
+        builder.setUseBigDecimalForObjectNumbers(config.getProperty("johnzon.use-big-decimal-for-object").map(this::toBool).orElse(true));
+        builder.setMaxBigDecimalScale(config.getProperty("johnzon.max-big-decimal-scale").map(this::toInt).orElse(1000));
 
         builder.setSupportEnumContainerDeserialization( // https://github.com/eclipse-ee4j/jakartaee-tck/issues/103
                 toBool(System.getProperty("johnzon.support-enum-container-deserialization", config.getProperty("johnzon.support-enum-container-deserialization")
@@ -284,10 +282,8 @@ public class JohnzonBuilder implements JsonbBuilder {
             getBeanManager(); // force detection
         }
 
-        builder.setReadAttributeBeforeWrite(
-                config.getProperty("johnzon.readAttributeBeforeWrite").map(Boolean.class::cast).orElse(false));
-        builder.setAutoAdjustStringBuffers(
-                config.getProperty("johnzon.autoAdjustBuffer").map(Boolean.class::cast).orElse(true));
+        builder.setReadAttributeBeforeWrite(config.getProperty("johnzon.readAttributeBeforeWrite").map(Boolean.class::cast).orElse(false));
+        builder.setAutoAdjustStringBuffers(config.getProperty("johnzon.autoAdjustBuffer").map(Boolean.class::cast).orElse(true));
         config.getProperty("johnzon.serialize-value-filter")
                 .map(s -> {
                     if (String.class.isInstance(s)) {
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
index d512b419..4307d11d 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperConfigTest.java
@@ -169,7 +169,7 @@ public class MapperConfigTest {
                                 new FieldAccessMode(true, true),
                                 StandardCharsets.UTF_8,
                                 null,
-                                false, null, false, false, emptyMap(), true, false, true,
+                                false, null, false, false, emptyMap(), true, false, 1000, true,
                                 null, null, null, null, null,
                                 type -> new EnumConverter(type));
     }
diff --git a/johnzon-mapper/src/test/java/org/superbiz/ExtendMappingTest.java b/johnzon-mapper/src/test/java/org/superbiz/ExtendMappingTest.java
index febe682d..83bb883d 100644
--- a/johnzon-mapper/src/test/java/org/superbiz/ExtendMappingTest.java
+++ b/johnzon-mapper/src/test/java/org/superbiz/ExtendMappingTest.java
@@ -62,8 +62,8 @@ public class ExtendMappingTest {
                     -1, true, true, true, false, false, false,
                     new FieldAccessMode(false, false),
                     StandardCharsets.UTF_8, String::compareTo, false, null, false, false,
-                    emptyMap(), true, false, true,
-                    null, null, null, null, null,
+                    emptyMap(), true, false,1000, true, null,
+                    null, null, null, null,
                     type -> new EnumConverter(type)));
         }