From dd6a58ee4aaeb88416b33d6fa8807495c4d3db59 Mon Sep 17 00:00:00 2001 From: Julien Viet Date: Wed, 31 Jan 2024 11:19:33 +0100 Subject: [PATCH] The upgrade to Jackson 2.16.x brought the new recycler pool feature. We should support Jackson versions that do not support this feature to avoid forcing users to move Jackson 2.16.x Use reflection to configure the pool instead and gracefully fail when configuration cannot be achieved. --- pom.xml | 25 ++++++++++- .../vertx/core/json/jackson/JacksonCodec.java | 31 ++++++++++---- .../vertx/it/NoRecyclerPoolJacksonTest.java | 41 +++++++++++++++++++ 3 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 src/test/java/io/vertx/it/NoRecyclerPoolJacksonTest.java diff --git a/pom.xml b/pom.xml index b552c3e08b0..c4d58b5e9fd 100644 --- a/pom.xml +++ b/pom.xml @@ -416,7 +416,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.19.1 + 3.2.5 ssl-engine:default @@ -571,6 +571,29 @@ + + no-recycler-pool-jackson + + integration-test + verify + + + + io/vertx/it/NoRecyclerPoolJacksonTest.java + + + + com.fasterxml.jackson.core + jackson-core + 2.15.1 + + + + com.fasterxml.jackson.core:jackson-core + com.fasterxml.jackson.core:jackson-databind + + + no-jackson-databind diff --git a/src/main/java/io/vertx/core/json/jackson/JacksonCodec.java b/src/main/java/io/vertx/core/json/jackson/JacksonCodec.java index b4a7da95fa2..0d7308068e5 100644 --- a/src/main/java/io/vertx/core/json/jackson/JacksonCodec.java +++ b/src/main/java/io/vertx/core/json/jackson/JacksonCodec.java @@ -11,11 +11,7 @@ package io.vertx.core.json.jackson; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.JsonTokenId; +import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.type.TypeReference; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; @@ -35,6 +31,7 @@ import java.io.OutputStream; import java.io.StringWriter; import java.io.Writer; +import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.math.BigDecimal; @@ -54,11 +51,31 @@ */ public class JacksonCodec implements JsonCodec { - private static final JsonFactory factory = JsonFactory.builder().recyclerPool(HybridJacksonPool.getInstance()).build(); + private static JsonFactory buildFactory() { + TSFBuilder builder = JsonFactory.builder(); + try { + // Use reflection to configure the recycler pool + Method[] methods = builder.getClass().getMethods(); + for (Method method : methods) { + if (method.getName().equals("recyclerPool")) { + Class poolClass = JacksonCodec.class.getClassLoader().loadClass("io.vertx.core.json.jackson.HybridJacksonPool"); + Method getInstanceMethod = poolClass.getMethod("getInstance"); + Object pool = getInstanceMethod.invoke(null); + method.invoke(builder, pool); + break; + } + } + } catch (Throwable e) { + // Ignore: most likely no Recycler Pool with Jackson < 2.16 + } + return builder.build(); + } + + private static final JsonFactory factory = buildFactory(); static { // Non-standard JSON but we allow C style comments in our JSON - factory.configure(JsonParser.Feature.ALLOW_COMMENTS, true); + JacksonCodec.factory.configure(JsonParser.Feature.ALLOW_COMMENTS, true); } @Override diff --git a/src/test/java/io/vertx/it/NoRecyclerPoolJacksonTest.java b/src/test/java/io/vertx/it/NoRecyclerPoolJacksonTest.java new file mode 100644 index 00000000000..aed6a7392c9 --- /dev/null +++ b/src/test/java/io/vertx/it/NoRecyclerPoolJacksonTest.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ + +package io.vertx.it; + +import com.fasterxml.jackson.core.Version; +import io.vertx.core.json.DecodeException; +import io.vertx.core.json.JsonObject; +import io.vertx.test.core.VertxTestBase; +import org.junit.Test; + +/** + * @author Julien Viet + */ +public class NoRecyclerPoolJacksonTest extends VertxTestBase { + + @Test + public void testJsonObject() { + + Version version = com.fasterxml.jackson.core.json.PackageVersion.VERSION; + assertEquals("2.15.1", version.toString()); + + JsonObject obj = new JsonObject("{\"foo\":\"bar\"}"); + assertEquals("bar", obj.getString("foo")); + assertEquals("{\"foo\":\"bar\"}", obj.toString()); + try { + obj.mapTo(Object.class); + fail(); + } catch (DecodeException ignore) { + // Expected + } + } +}