From ce3d39806f3de1acdfad45cf91613358049ccac0 Mon Sep 17 00:00:00 2001 From: Phillip Kruger Date: Thu, 2 Jul 2026 14:02:41 +1000 Subject: [PATCH 1/2] Migrate from Jackson 2.x to Jackson 3.1.4 Aligns with Quarkus 4 which targets Jackson 3.x (tools.jackson:jackson-bom:3.1.4). Key changes: - Maven groupId: com.fasterxml.jackson -> tools.jackson (except annotations) - Java packages: com.fasterxml.jackson.databind/core -> tools.jackson.databind/core - JsonSerializer/JsonDeserializer -> ValueSerializer/ValueDeserializer - JsonProcessingException -> JacksonException (now unchecked) - ObjectMapper is now immutable: use JsonMapper.builder() pattern - jackson-datatype-jdk8 and jackson-datatype-jsr310 removed (built into databind) - AnnotationIntrospector API updated for Jackson 3 signatures --- client/api/pom.xml | 2 +- .../io/smallrye/graphql/client/Request.java | 2 +- .../io/smallrye/graphql/client/Response.java | 2 +- .../client/typesafe/api/TypesafeResponse.java | 3 +- client/implementation-vertx/pom.xml | 6 +- .../dynamic/VertxDynamicGraphQLClient.java | 3 +- .../VertxTypesafeGraphQLClientProxy.java | 11 +- .../WebSocketSubprotocolHandler.java | 3 +- .../GraphQLTransportWSSubprotocolHandler.java | 13 +- .../GraphQLWSSubprotocolHandler.java | 11 +- .../test/DynamicClientExceptionTest.java | 3 +- .../VertxTypesafeGraphQLClientFixture.java | 7 +- client/implementation/pom.xml | 10 +- .../graphql/client/impl/RequestImpl.java | 17 ++- .../graphql/client/impl/ResponseImpl.java | 9 +- .../graphql/client/impl/ResponseReader.java | 23 ++-- .../impl/SmallRyeGraphQLClientLogging.java | 2 +- .../client/impl/typesafe/ResultBuilder.java | 11 +- .../impl/typesafe/json/JsonArrayReader.java | 5 +- .../impl/typesafe/json/JsonBooleanReader.java | 3 +- .../impl/typesafe/json/JsonMapReader.java | 7 +- .../impl/typesafe/json/JsonNullReader.java | 3 +- .../impl/typesafe/json/JsonNumberReader.java | 3 +- .../impl/typesafe/json/JsonObjectReader.java | 5 +- .../client/impl/typesafe/json/JsonReader.java | 7 +- .../impl/typesafe/json/JsonStringReader.java | 3 +- .../client/impl/typesafe/json/JsonUtils.java | 8 +- .../client/impl/typesafe/json/Reader.java | 3 +- .../graphql/client/RequestImplTest.java | 3 +- client/tck/pom.xml | 2 +- .../typesafe/TypesafeResponseBehavior.java | 11 +- common/jackson-jsonb-compat/pom.xml | 10 +- .../jsonb/JsonbAnnotationIntrospector.java | 44 +++--- .../jackson/jsonb/JsonbCompatModule.java | 2 +- .../jsonb/JsonbDateFormatDeserializer.java | 16 +-- .../jsonb/JsonbDateFormatSerializer.java | 11 +- .../jsonb/JsonbNumberFormatDeserializer.java | 19 ++- .../jsonb/JsonbNumberFormatSerializer.java | 13 +- .../JsonbAnnotationIntrospectorTest.java | 17 +-- common/schema-builder/pom.xml | 2 +- .../smallrye/graphql/schema/Annotations.java | 4 +- .../schema/helper/AdaptWithHelper.java | 2 +- .../graphql/index/SchemaBuilderTest.java | 12 +- .../graphql/schema/model/Scalars.java | 4 +- docs/pom.xml | 2 +- .../examples/dynamicclient/MyClientUsage.java | 2 +- pom.xml | 4 +- .../graphql/execution/CdiExecutionTest.java | 5 +- server/implementation-servlet/pom.xml | 2 +- .../servlet/HttpServletResponseWriter.java | 6 +- server/implementation/pom.xml | 10 +- .../smallrye/graphql/bootstrap/Bootstrap.java | 9 +- .../graphql/execution/ExecutionResponse.java | 34 ++--- .../datafetcher/DataFetcherException.java | 15 +- .../datafetcher/helper/ArgumentHelper.java | 15 +- .../datafetcher/helper/DefaultMapAdapter.java | 7 +- .../error/ExecutionErrorsService.java | 14 +- .../graphql/execution/event/EventEmitter.java | 3 +- .../graphql/json/GraphQLNamingStrategy.java | 2 +- .../smallrye/graphql/json/JacksonCreator.java | 128 +++++++++--------- .../graphql/json/JsonInputRegistry.java | 3 +- .../graphql/scalar/GraphQLScalarTypes.java | 4 +- .../smallrye/graphql/spi/EventingService.java | 3 +- .../error/ExecutionErrorsServiceTest.java | 5 +- .../dynamic/DynamicClientInjectionTest.java | 3 +- ...DynamicClientSingleOperationsTestBase.java | 3 +- .../client/dynamic/NestedRecordsTest.java | 5 +- .../tests/client/dynamic/RecordTest.java | 4 +- .../DynamicClientInboundExtensionsTest.java | 8 +- .../fragments/DynamicClientFragmentTest.java | 5 +- .../tests/json/CustomJsonbService.java | 9 +- .../SubscriptionFieldBatchingTest.java | 3 +- server/tck/pom.xml | 2 +- 73 files changed, 300 insertions(+), 372 deletions(-) diff --git a/client/api/pom.xml b/client/api/pom.xml index 7aa5acda1..80fd43af9 100644 --- a/client/api/pom.xml +++ b/client/api/pom.xml @@ -40,7 +40,7 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind provided diff --git a/client/api/src/main/java/io/smallrye/graphql/client/Request.java b/client/api/src/main/java/io/smallrye/graphql/client/Request.java index 027bf982c..d4cfa094d 100644 --- a/client/api/src/main/java/io/smallrye/graphql/client/Request.java +++ b/client/api/src/main/java/io/smallrye/graphql/client/Request.java @@ -2,7 +2,7 @@ import java.util.Map; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.ObjectNode; public interface Request { String getDocument(); diff --git a/client/api/src/main/java/io/smallrye/graphql/client/Response.java b/client/api/src/main/java/io/smallrye/graphql/client/Response.java index b77b41ded..d2c586d33 100644 --- a/client/api/src/main/java/io/smallrye/graphql/client/Response.java +++ b/client/api/src/main/java/io/smallrye/graphql/client/Response.java @@ -3,7 +3,7 @@ import java.util.List; import java.util.Map; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.ObjectNode; public interface Response { diff --git a/client/api/src/main/java/io/smallrye/graphql/client/typesafe/api/TypesafeResponse.java b/client/api/src/main/java/io/smallrye/graphql/client/typesafe/api/TypesafeResponse.java index 81b594ee9..0739a4184 100644 --- a/client/api/src/main/java/io/smallrye/graphql/client/typesafe/api/TypesafeResponse.java +++ b/client/api/src/main/java/io/smallrye/graphql/client/typesafe/api/TypesafeResponse.java @@ -7,9 +7,8 @@ import java.util.Map; import java.util.Objects; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLError; +import tools.jackson.databind.node.ObjectNode; public final class TypesafeResponse extends ErrorOr { private Map> transportMeta; diff --git a/client/implementation-vertx/pom.xml b/client/implementation-vertx/pom.xml index 578134ba7..50fb44349 100644 --- a/client/implementation-vertx/pom.xml +++ b/client/implementation-vertx/pom.xml @@ -29,13 +29,9 @@ microprofile-config-api - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - io.smallrye smallrye-graphql-jackson-jsonb-compat diff --git a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClient.java b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClient.java index 5a6e6f5a9..3b8062be9 100644 --- a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClient.java +++ b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClient.java @@ -13,8 +13,6 @@ import org.jboss.logging.Logger; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.Request; import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.core.Document; @@ -41,6 +39,7 @@ import io.vertx.ext.web.client.HttpResponse; import io.vertx.ext.web.client.WebClient; import io.vertx.ext.web.client.WebClientOptions; +import tools.jackson.databind.node.ObjectNode; public class VertxDynamicGraphQLClient implements DynamicGraphQLClient { diff --git a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java index 2c6921e10..691d23179 100644 --- a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java +++ b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/typesafe/VertxTypesafeGraphQLClientProxy.java @@ -24,12 +24,6 @@ import org.jboss.logging.Logger; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.InvalidResponseException; import io.smallrye.graphql.client.impl.RequestImpl; import io.smallrye.graphql.client.impl.discovery.ServiceURLSupplier; @@ -55,6 +49,11 @@ import io.vertx.core.http.WebSocketConnectOptions; import io.vertx.ext.web.client.HttpResponse; import io.vertx.ext.web.client.WebClient; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; class VertxTypesafeGraphQLClientProxy { diff --git a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/WebSocketSubprotocolHandler.java b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/WebSocketSubprotocolHandler.java index 07e81e7f1..40a7273fa 100644 --- a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/WebSocketSubprotocolHandler.java +++ b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/WebSocketSubprotocolHandler.java @@ -1,10 +1,9 @@ package io.smallrye.graphql.client.vertx.websocket; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.subscription.MultiEmitter; import io.smallrye.mutiny.subscription.UniEmitter; +import tools.jackson.databind.node.ObjectNode; /** * An implementation of this interface is responsible for handling a particular subscription websocket protocol. diff --git a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/graphqltransportws/GraphQLTransportWSSubprotocolHandler.java b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/graphqltransportws/GraphQLTransportWSSubprotocolHandler.java index 3bf86d7ca..c9e8ff3cf 100644 --- a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/graphqltransportws/GraphQLTransportWSSubprotocolHandler.java +++ b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/graphqltransportws/GraphQLTransportWSSubprotocolHandler.java @@ -10,12 +10,6 @@ import org.jboss.logging.Logger; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLClientException; import io.smallrye.graphql.client.GraphQLError; import io.smallrye.graphql.client.InvalidResponseException; @@ -30,6 +24,11 @@ import io.smallrye.mutiny.subscription.MultiEmitter; import io.smallrye.mutiny.subscription.UniEmitter; import io.vertx.core.http.WebSocket; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; /** * Implementation of the `graphql-transport-ws` protocol. The protocol specification is at @@ -302,7 +301,7 @@ private MessageType getMessageType(ObjectNode message) { private ObjectNode parseIncomingMessage(String message) { try { return (ObjectNode) MAPPER.readTree(message); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalArgumentException("Failed to parse incoming message", e); } } diff --git a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/graphqlws/GraphQLWSSubprotocolHandler.java b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/graphqlws/GraphQLWSSubprotocolHandler.java index bed7f92da..e16d7e2ff 100644 --- a/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/graphqlws/GraphQLWSSubprotocolHandler.java +++ b/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/websocket/graphqlws/GraphQLWSSubprotocolHandler.java @@ -8,11 +8,6 @@ import org.jboss.logging.Logger; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLClientException; import io.smallrye.graphql.client.GraphQLError; import io.smallrye.graphql.client.InvalidResponseException; @@ -27,6 +22,10 @@ import io.smallrye.mutiny.subscription.MultiEmitter; import io.smallrye.mutiny.subscription.UniEmitter; import io.vertx.core.http.WebSocket; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ObjectNode; /** * Handler for the legacy `graphql-ws` subprotocol @@ -210,7 +209,7 @@ public void close() { private ObjectNode parseIncomingMessage(String message) { try { return (ObjectNode) MAPPER.readTree(message); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new IllegalArgumentException("Failed to parse incoming message", e); } } diff --git a/client/implementation-vertx/src/test/java/io/smallrye/graphql/client/vertx/test/DynamicClientExceptionTest.java b/client/implementation-vertx/src/test/java/io/smallrye/graphql/client/vertx/test/DynamicClientExceptionTest.java index fda8ffa50..af098bbfa 100644 --- a/client/implementation-vertx/src/test/java/io/smallrye/graphql/client/vertx/test/DynamicClientExceptionTest.java +++ b/client/implementation-vertx/src/test/java/io/smallrye/graphql/client/vertx/test/DynamicClientExceptionTest.java @@ -8,8 +8,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.InvalidResponseException; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClientBuilder; @@ -17,6 +15,7 @@ import io.vertx.core.Vertx; import io.vertx.core.http.HttpServer; import io.vertx.core.http.HttpServerOptions; +import tools.jackson.databind.node.ObjectNode; /** * Make sure than when executing a sync operation with a dynamic client and diff --git a/client/implementation-vertx/src/test/java/test/tck/VertxTypesafeGraphQLClientFixture.java b/client/implementation-vertx/src/test/java/test/tck/VertxTypesafeGraphQLClientFixture.java index e489227d4..403a677db 100644 --- a/client/implementation-vertx/src/test/java/test/tck/VertxTypesafeGraphQLClientFixture.java +++ b/client/implementation-vertx/src/test/java/test/tck/VertxTypesafeGraphQLClientFixture.java @@ -13,9 +13,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - import io.smallrye.graphql.client.typesafe.api.TypesafeGraphQLClientBuilder; import io.smallrye.graphql.client.vertx.typesafe.VertxTypesafeGraphQLClientBuilder; import io.vertx.core.MultiMap; @@ -25,6 +22,8 @@ import io.vertx.ext.web.client.HttpResponse; import io.vertx.ext.web.client.WebClient; import tck.graphql.typesafe.TypesafeGraphQLClientFixture; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; public class VertxTypesafeGraphQLClientFixture implements TypesafeGraphQLClientFixture { private final WebClient mockWebClient = Mockito.mock(WebClient.class); @@ -141,7 +140,7 @@ private JsonNode requestSent() { then(mockHttpRequest).should().sendBuffer(captor.capture()); String requestString = captor.getValue().toString(); try { - requestSent = new ObjectMapper().readTree(requestString); + requestSent = JsonMapper.builder().build().readTree(requestString); } catch (Exception e) { throw new RuntimeException("Failed to parse request JSON", e); } diff --git a/client/implementation/pom.xml b/client/implementation/pom.xml index 27a700273..3c2e044cb 100644 --- a/client/implementation/pom.xml +++ b/client/implementation/pom.xml @@ -67,17 +67,9 @@ provided - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - io.smallrye smallrye-graphql-jackson-jsonb-compat diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/RequestImpl.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/RequestImpl.java index 3ad4003c7..91cfd7371 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/RequestImpl.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/RequestImpl.java @@ -4,20 +4,19 @@ import java.util.Map; import java.util.Objects; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.json.JsonMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.Request; import io.smallrye.graphql.jackson.jsonb.JsonbCompatModule; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; public class RequestImpl implements Request { public static final ObjectMapper MAPPER = JsonMapper.builder() .addModule(new JsonbCompatModule()) - .enable(com.fasterxml.jackson.databind.DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) - .disable(com.fasterxml.jackson.databind.cfg.JsonNodeFeature.STRIP_TRAILING_BIGDECIMAL_ZEROES) + .enable(tools.jackson.databind.DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) + .disable(tools.jackson.databind.cfg.JsonNodeFeature.STRIP_TRAILING_BIGDECIMAL_ZEROES) .build(); private final String document; @@ -78,7 +77,7 @@ public RequestImpl build() { public String toJson() { try { return MAPPER.writeValueAsString(toJsonObject()); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException("Failed to serialize request to JSON", e); } } diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseImpl.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseImpl.java index b9b6bd0d8..c21a29219 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseImpl.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseImpl.java @@ -8,15 +8,14 @@ import java.util.Map; import java.util.Set; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLClientException; import io.smallrye.graphql.client.GraphQLError; import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.impl.typesafe.json.JsonReader; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; public class ResponseImpl implements Response { @@ -144,7 +143,7 @@ private Object getScalarValue(JsonNode value) { */ private static Set fieldNames(ObjectNode node) { Set names = new LinkedHashSet<>(); - node.fieldNames().forEachRemaining(names::add); + node.propertyNames().forEach(names::add); return names; } diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseReader.java index e4dd866a8..4532447f7 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/ResponseReader.java @@ -8,14 +8,13 @@ import org.jboss.logging.Logger; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLError; import io.smallrye.graphql.client.InvalidResponseException; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; public class ResponseReader { private static final Logger LOG = Logger.getLogger(ResponseReader.class.getName()); @@ -50,16 +49,14 @@ public static ObjectNode parseGraphQLResponse(String input, Boolean allowUnexpec } else { return null; } - } catch (JsonProcessingException e) { + } catch (JacksonException e) { return null; } } private static ObjectNode checkExpectedResponseFields(ObjectNode jsonResponse, Boolean allowUnexpectedResponseFields) { - var fieldNames = jsonResponse.fieldNames(); - while (fieldNames.hasNext()) { - String key = fieldNames.next(); + for (String key : jsonResponse.propertyNames()) { if (!key.equalsIgnoreCase("data") && !key.equalsIgnoreCase("errors") && !key.equalsIgnoreCase("extensions")) { @@ -143,7 +140,7 @@ public static GraphQLError readError(JsonNode errorJson) { for (JsonNode jsonValue : locations) { ObjectNode location = (ObjectNode) jsonValue; Map map = new HashMap<>(); - location.fields().forEachRemaining(entry -> { + location.properties().forEach(entry -> { // TODO: how to handle non-numeric location segments? if (entry.getValue().isNumber()) { map.put(entry.getKey(), entry.getValue().intValue()); @@ -187,7 +184,7 @@ public static GraphQLError readError(JsonNode errorJson) { && errorObject.get("extensions").isObject()) { ObjectNode extensions = (ObjectNode) errorObject.get("extensions"); Map extensionMap = new HashMap<>(); - extensions.fields().forEachRemaining(entry -> { + extensions.properties().forEach(entry -> { extensionMap.put(entry.getKey(), decode(entry.getValue())); }); decodedError.setExtensions(extensionMap); @@ -201,7 +198,7 @@ public static GraphQLError readError(JsonNode errorJson) { try { // check if there are any other fields beyond the ones described by the specification Map otherFields = new HashMap<>(); - errorObject.fieldNames().forEachRemaining(key -> { + errorObject.propertyNames().forEach(key -> { if (!key.equals("extensions") && !key.equals("locations") && !key.equals("message") && diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/SmallRyeGraphQLClientLogging.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/SmallRyeGraphQLClientLogging.java index 89d23e008..fcbd7d437 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/SmallRyeGraphQLClientLogging.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/SmallRyeGraphQLClientLogging.java @@ -7,7 +7,7 @@ import org.jboss.logging.annotations.Message; import org.jboss.logging.annotations.MessageLogger; -import com.fasterxml.jackson.databind.node.JsonNodeType; +import tools.jackson.databind.node.JsonNodeType; @MessageLogger(projectCode = "SRGQL") public interface SmallRyeGraphQLClientLogging { diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/ResultBuilder.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/ResultBuilder.java index 4bf2c6cd0..e15bc0b67 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/ResultBuilder.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/ResultBuilder.java @@ -7,12 +7,6 @@ import java.util.Map; import java.util.stream.StreamSupport; -import com.fasterxml.jackson.core.JsonPointer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLClientException; import io.smallrye.graphql.client.InvalidResponseException; import io.smallrye.graphql.client.impl.RequestImpl; @@ -22,6 +16,11 @@ import io.smallrye.graphql.client.impl.typesafe.reflection.MethodInvocation; import io.smallrye.graphql.client.typesafe.api.ErrorOr; import io.smallrye.graphql.client.typesafe.api.TypesafeResponse; +import tools.jackson.core.JsonPointer; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; public class ResultBuilder { private static final ObjectMapper MAPPER = RequestImpl.MAPPER; diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonArrayReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonArrayReader.java index f3e127e51..54a26cdd6 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonArrayReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonArrayReader.java @@ -9,13 +9,12 @@ import java.util.stream.Collector; import java.util.stream.StreamSupport; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; - import io.smallrye.graphql.client.InvalidResponseException; import io.smallrye.graphql.client.impl.typesafe.CollectionUtils; import io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; class JsonArrayReader extends Reader { diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonBooleanReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonBooleanReader.java index 1f296a47c..276ba3e50 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonBooleanReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonBooleanReader.java @@ -1,9 +1,8 @@ package io.smallrye.graphql.client.impl.typesafe.json; -import com.fasterxml.jackson.databind.JsonNode; - import io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; class JsonBooleanReader extends Reader { JsonBooleanReader(TypeInfo type, Location location, JsonNode value, FieldInfo field) { diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonMapReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonMapReader.java index 2154ab1af..8641f788b 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonMapReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonMapReader.java @@ -3,12 +3,11 @@ import java.util.HashMap; import java.util.Map; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; - import io.smallrye.graphql.client.InvalidResponseException; import io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; class JsonMapReader extends Reader { @@ -49,7 +48,7 @@ Object read() { Object keyDeserialized = JsonReader.readJson(keyLocation, keyType, keyJson, field); Object valueDeserialized = JsonReader.readJson(valueLocation, valueType, - valueJson != null ? valueJson : com.fasterxml.jackson.databind.node.NullNode.getInstance(), field); + valueJson != null ? valueJson : tools.jackson.databind.node.NullNode.getInstance(), field); result.put(keyDeserialized, valueDeserialized); } diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonNullReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonNullReader.java index f6cfaaa5b..397982cf1 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonNullReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonNullReader.java @@ -2,10 +2,9 @@ import static io.smallrye.graphql.client.impl.typesafe.json.GraphQLClientValueHelper.check; -import com.fasterxml.jackson.databind.JsonNode; - import io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; class JsonNullReader extends Reader { JsonNullReader(TypeInfo type, Location location, JsonNode value, FieldInfo field) { diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonNumberReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonNumberReader.java index 4a19449fa..3696e375c 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonNumberReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonNumberReader.java @@ -6,10 +6,9 @@ import java.util.OptionalInt; import java.util.OptionalLong; -import com.fasterxml.jackson.databind.JsonNode; - import io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; class JsonNumberReader extends Reader { JsonNumberReader(TypeInfo type, Location location, JsonNode value, FieldInfo field) { diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonObjectReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonObjectReader.java index 416fad35a..a78a5eab6 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonObjectReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonObjectReader.java @@ -6,13 +6,12 @@ import java.util.Map; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.InvalidResponseException; import io.smallrye.graphql.client.impl.SmallRyeGraphQLClientMessages; import io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ObjectNode; class JsonObjectReader extends Reader { JsonObjectReader(TypeInfo type, Location location, ObjectNode value, FieldInfo field) { diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonReader.java index 4033c11f1..622ab8cda 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonReader.java @@ -10,10 +10,6 @@ import java.util.OptionalLong; import java.util.stream.StreamSupport; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLClientException; import io.smallrye.graphql.client.GraphQLError; import io.smallrye.graphql.client.InvalidResponseException; @@ -22,6 +18,9 @@ import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; import io.smallrye.graphql.client.typesafe.api.ErrorOr; import io.smallrye.graphql.client.typesafe.api.TypesafeResponse; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; public class JsonReader extends Reader { public static Object readJson(String description, TypeInfo type, JsonNode value, FieldInfo field) { diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonStringReader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonStringReader.java index cc7f24ecf..7708d0d74 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonStringReader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonStringReader.java @@ -14,12 +14,11 @@ import org.eclipse.microprofile.graphql.DateFormat; import org.eclipse.microprofile.graphql.NumberFormat; -import com.fasterxml.jackson.databind.JsonNode; - import io.smallrye.graphql.client.InvalidResponseException; import io.smallrye.graphql.client.impl.typesafe.reflection.ConstructionInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; class JsonStringReader extends Reader { JsonStringReader(TypeInfo type, Location location, JsonNode value, FieldInfo field) { diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonUtils.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonUtils.java index 1c7d039b8..91627a672 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonUtils.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/JsonUtils.java @@ -5,9 +5,9 @@ import java.util.List; import java.util.Map; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; public class JsonUtils { public static Object toValue(JsonNode value) { @@ -42,7 +42,7 @@ public static Map toMap(ObjectNode jsonObject) { if (jsonObject == null) return null; Map map = new LinkedHashMap<>(); - jsonObject.fields().forEachRemaining(entry -> map.put(entry.getKey(), toValue(entry.getValue()))); + jsonObject.properties().forEach(entry -> map.put(entry.getKey(), toValue(entry.getValue()))); return map; } diff --git a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/Reader.java b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/Reader.java index c939a9d7c..cfe2db257 100644 --- a/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/Reader.java +++ b/client/implementation/src/main/java/io/smallrye/graphql/client/impl/typesafe/json/Reader.java @@ -2,10 +2,9 @@ import static java.util.Objects.requireNonNull; -import com.fasterxml.jackson.databind.JsonNode; - import io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo; import io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo; +import tools.jackson.databind.JsonNode; abstract class Reader { protected final TypeInfo type; diff --git a/client/implementation/src/test/java/io/smallrye/graphql/client/RequestImplTest.java b/client/implementation/src/test/java/io/smallrye/graphql/client/RequestImplTest.java index 92f2a3588..4fcc07b4e 100644 --- a/client/implementation/src/test/java/io/smallrye/graphql/client/RequestImplTest.java +++ b/client/implementation/src/test/java/io/smallrye/graphql/client/RequestImplTest.java @@ -8,9 +8,8 @@ import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.impl.RequestImpl; +import tools.jackson.databind.node.ObjectNode; /** * Validates the JSON serialization of the query and variables in a RequestImpl diff --git a/client/tck/pom.xml b/client/tck/pom.xml index ecea52857..35235be21 100644 --- a/client/tck/pom.xml +++ b/client/tck/pom.xml @@ -40,7 +40,7 @@ jakarta.enterprise.cdi-api - com.fasterxml.jackson.core + tools.jackson.core jackson-databind diff --git a/client/tck/src/main/java/tck/graphql/typesafe/TypesafeResponseBehavior.java b/client/tck/src/main/java/tck/graphql/typesafe/TypesafeResponseBehavior.java index 6dbae320f..176149637 100644 --- a/client/tck/src/main/java/tck/graphql/typesafe/TypesafeResponseBehavior.java +++ b/client/tck/src/main/java/tck/graphql/typesafe/TypesafeResponseBehavior.java @@ -9,12 +9,12 @@ import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLError; import io.smallrye.graphql.client.typesafe.api.GraphQLClientApi; import io.smallrye.graphql.client.typesafe.api.TypesafeResponse; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; public class TypesafeResponseBehavior { private final TypesafeGraphQLClientFixture fixture = TypesafeGraphQLClientFixture.load(); @@ -52,8 +52,9 @@ void shouldParseExtensionsInTypesafeResponse() throws Exception { TypesafeResponse result = api.greetings(); then(fixture.query()).isEqualTo("query greetings { greetings }"); - ObjectMapper mapper = new ObjectMapper() - .enable(com.fasterxml.jackson.databind.DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS); + ObjectMapper mapper = JsonMapper.builder() + .enable(tools.jackson.databind.DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS) + .build(); ObjectNode expectedExtensions = (ObjectNode) mapper.readTree("{\"pi\":3.14159,\"extension\":\"bell\"}"); then(result.getExtensions()).isEqualTo(expectedExtensions); then(result.getTransportMeta()).isEqualTo( diff --git a/common/jackson-jsonb-compat/pom.xml b/common/jackson-jsonb-compat/pom.xml index 983307d39..5cb46249c 100644 --- a/common/jackson-jsonb-compat/pom.xml +++ b/common/jackson-jsonb-compat/pom.xml @@ -15,17 +15,9 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - jakarta.json.bind jakarta.json.bind-api diff --git a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbAnnotationIntrospector.java b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbAnnotationIntrospector.java index 1de82ff03..48b790e00 100644 --- a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbAnnotationIntrospector.java +++ b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbAnnotationIntrospector.java @@ -15,25 +15,23 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.PropertyName; -import com.fasterxml.jackson.databind.cfg.MapperConfig; -import com.fasterxml.jackson.databind.introspect.Annotated; -import com.fasterxml.jackson.databind.introspect.AnnotatedClass; -import com.fasterxml.jackson.databind.introspect.AnnotatedField; -import com.fasterxml.jackson.databind.introspect.AnnotatedMember; -import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; -import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector; -import com.fasterxml.jackson.databind.jsontype.NamedType; -import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; -import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder; + +import tools.jackson.databind.PropertyName; +import tools.jackson.databind.cfg.MapperConfig; +import tools.jackson.databind.introspect.Annotated; +import tools.jackson.databind.introspect.AnnotatedField; +import tools.jackson.databind.introspect.AnnotatedMember; +import tools.jackson.databind.introspect.AnnotatedMethod; +import tools.jackson.databind.introspect.NopAnnotationIntrospector; +import tools.jackson.databind.jsontype.NamedType; +import tools.jackson.databind.jsontype.impl.StdTypeResolverBuilder; public class JsonbAnnotationIntrospector extends NopAnnotationIntrospector { private static final long serialVersionUID = 1L; @Override - public PropertyName findNameForSerialization(Annotated a) { + public PropertyName findNameForSerialization(MapperConfig config, Annotated a) { JsonbProperty prop = a.getAnnotation(JsonbProperty.class); if (prop != null && !prop.value().isEmpty()) { return PropertyName.construct(prop.value()); @@ -42,7 +40,7 @@ public PropertyName findNameForSerialization(Annotated a) { } @Override - public PropertyName findNameForDeserialization(Annotated a) { + public PropertyName findNameForDeserialization(MapperConfig config, Annotated a) { JsonbProperty prop = a.getAnnotation(JsonbProperty.class); if (prop != null && !prop.value().isEmpty()) { return PropertyName.construct(prop.value()); @@ -51,12 +49,12 @@ public PropertyName findNameForDeserialization(Annotated a) { } @Override - public boolean hasIgnoreMarker(AnnotatedMember m) { + public boolean hasIgnoreMarker(MapperConfig config, AnnotatedMember m) { return m.hasAnnotation(JsonbTransient.class); } @Override - public JsonInclude.Value findPropertyInclusion(Annotated a) { + public JsonInclude.Value findPropertyInclusion(MapperConfig config, Annotated a) { // Field-level: @JsonbProperty(nillable = true) JsonbProperty prop = a.getAnnotation(JsonbProperty.class); if (prop != null && prop.nillable()) { @@ -77,7 +75,7 @@ public JsonInclude.Value findPropertyInclusion(Annotated a) { } @Override - public Object findSerializer(Annotated a) { + public Object findSerializer(MapperConfig config, Annotated a) { JsonbDateFormat dateFormat = a.getAnnotation(JsonbDateFormat.class); if (dateFormat != null) { return new JsonbDateFormatSerializer(dateFormat.value(), dateFormat.locale()); @@ -90,7 +88,7 @@ public Object findSerializer(Annotated a) { } @Override - public Object findDeserializer(Annotated a) { + public Object findDeserializer(MapperConfig config, Annotated a) { JsonbDateFormat dateFormat = a.getAnnotation(JsonbDateFormat.class); if (dateFormat != null) { Class rawType = resolveRawType(a); @@ -119,20 +117,16 @@ private Class resolveRawType(Annotated a) { } @Override - public TypeResolverBuilder findTypeResolver(MapperConfig config, AnnotatedClass ac, JavaType baseType) { + public Object findTypeResolverBuilder(MapperConfig config, Annotated ac) { JsonbTypeInfo typeInfo = ac.getAnnotation(JsonbTypeInfo.class); if (typeInfo != null) { - StdTypeResolverBuilder builder = new StdTypeResolverBuilder(); - builder.init(JsonTypeInfo.Id.NAME, null); - builder.inclusion(JsonTypeInfo.As.PROPERTY); - builder.typeProperty(typeInfo.key()); - return builder; + return new StdTypeResolverBuilder(JsonTypeInfo.Id.NAME, JsonTypeInfo.As.PROPERTY, typeInfo.key()); } return null; } @Override - public List findSubtypes(Annotated a) { + public List findSubtypes(MapperConfig config, Annotated a) { JsonbTypeInfo typeInfo = a.getAnnotation(JsonbTypeInfo.class); if (typeInfo != null) { List subtypes = new ArrayList<>(); diff --git a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbCompatModule.java b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbCompatModule.java index 08cf44ee2..ca67af8dd 100644 --- a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbCompatModule.java +++ b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbCompatModule.java @@ -1,6 +1,6 @@ package io.smallrye.graphql.jackson.jsonb; -import com.fasterxml.jackson.databind.module.SimpleModule; +import tools.jackson.databind.module.SimpleModule; public class JsonbCompatModule extends SimpleModule { diff --git a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbDateFormatDeserializer.java b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbDateFormatDeserializer.java index dddb80eef..35803eab5 100644 --- a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbDateFormatDeserializer.java +++ b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbDateFormatDeserializer.java @@ -1,6 +1,5 @@ package io.smallrye.graphql.jackson.jsonb; -import java.io.IOException; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; @@ -14,13 +13,12 @@ import jakarta.json.bind.annotation.JsonbDateFormat; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.BeanProperty; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.deser.ContextualDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.BeanProperty; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ValueDeserializer; -public class JsonbDateFormatDeserializer extends JsonDeserializer implements ContextualDeserializer { +public class JsonbDateFormatDeserializer extends ValueDeserializer { private DateTimeFormatter formatter; private Class targetType; @@ -36,7 +34,7 @@ public JsonbDateFormatDeserializer(String pattern, String locale, Class targe } @Override - public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) { + public ValueDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) { if (property != null) { JsonbDateFormat ann = property.getAnnotation(JsonbDateFormat.class); if (ann != null) { @@ -48,7 +46,7 @@ public JsonDeserializer createContextual(DeserializationContext ctxt, BeanPro } @Override - public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public Object deserialize(JsonParser p, DeserializationContext ctxt) { String text = p.getText(); TemporalAccessor parsed = formatter.parse(text); diff --git a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbDateFormatSerializer.java b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbDateFormatSerializer.java index e0399cc0d..a6fcc22f6 100644 --- a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbDateFormatSerializer.java +++ b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbDateFormatSerializer.java @@ -1,15 +1,14 @@ package io.smallrye.graphql.jackson.jsonb; -import java.io.IOException; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAccessor; import java.util.Locale; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; -public class JsonbDateFormatSerializer extends JsonSerializer { +public class JsonbDateFormatSerializer extends ValueSerializer { private final DateTimeFormatter formatter; @@ -19,7 +18,7 @@ public JsonbDateFormatSerializer(String pattern, String locale) { } @Override - public void serialize(TemporalAccessor value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(TemporalAccessor value, JsonGenerator gen, SerializationContext serializers) { gen.writeString(formatter.format(value)); } } diff --git a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbNumberFormatDeserializer.java b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbNumberFormatDeserializer.java index 2af8ec598..826a3ff3f 100644 --- a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbNumberFormatDeserializer.java +++ b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbNumberFormatDeserializer.java @@ -1,6 +1,5 @@ package io.smallrye.graphql.jackson.jsonb; -import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.text.DecimalFormat; @@ -10,13 +9,13 @@ import jakarta.json.bind.annotation.JsonbNumberFormat; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.BeanProperty; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.deser.ContextualDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.BeanProperty; +import tools.jackson.databind.DatabindException; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ValueDeserializer; -public class JsonbNumberFormatDeserializer extends JsonDeserializer implements ContextualDeserializer { +public class JsonbNumberFormatDeserializer extends ValueDeserializer { private String pattern; private String locale; @@ -33,7 +32,7 @@ public JsonbNumberFormatDeserializer(String pattern, String locale, Class tar } @Override - public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) { + public ValueDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) { if (property != null) { JsonbNumberFormat ann = property.getAnnotation(JsonbNumberFormat.class); if (ann != null) { @@ -45,7 +44,7 @@ public JsonDeserializer createContextual(DeserializationContext ctxt, BeanPro } @Override - public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public Object deserialize(JsonParser p, DeserializationContext ctxt) { String text = p.getText(); Locale loc = resolveLocale(ctxt); DecimalFormat fmt = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance(loc)); @@ -55,7 +54,7 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx try { parsed = fmt.parse(text); } catch (ParseException e) { - throw new IOException("Failed to parse number from '" + text + "' with pattern '" + pattern + "'", e); + throw DatabindException.from(p, "Failed to parse number from '" + text + "' with pattern '" + pattern + "'", e); } if (targetType == int.class || targetType == Integer.class) { diff --git a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbNumberFormatSerializer.java b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbNumberFormatSerializer.java index f0df775d2..d6539cba8 100644 --- a/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbNumberFormatSerializer.java +++ b/common/jackson-jsonb-compat/src/main/java/io/smallrye/graphql/jackson/jsonb/JsonbNumberFormatSerializer.java @@ -1,15 +1,14 @@ package io.smallrye.graphql.jackson.jsonb; -import java.io.IOException; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Locale; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; +import tools.jackson.core.JsonGenerator; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueSerializer; -public class JsonbNumberFormatSerializer extends JsonSerializer { +public class JsonbNumberFormatSerializer extends ValueSerializer { private final String pattern; private final String locale; @@ -20,13 +19,13 @@ public JsonbNumberFormatSerializer(String pattern, String locale) { } @Override - public void serialize(Number value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + public void serialize(Number value, JsonGenerator gen, SerializationContext serializers) { Locale loc = resolveLocale(serializers); DecimalFormat fmt = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance(loc)); gen.writeString(fmt.format(value)); } - private Locale resolveLocale(SerializerProvider serializers) { + private Locale resolveLocale(SerializationContext serializers) { if (locale != null && !locale.isEmpty() && !jakarta.json.bind.annotation.JsonbNumberFormat.DEFAULT_LOCALE.equals(locale)) { return Locale.forLanguageTag(locale); diff --git a/common/jackson-jsonb-compat/src/test/java/io/smallrye/graphql/jackson/jsonb/JsonbAnnotationIntrospectorTest.java b/common/jackson-jsonb-compat/src/test/java/io/smallrye/graphql/jackson/jsonb/JsonbAnnotationIntrospectorTest.java index 59f4582f1..12766d84d 100644 --- a/common/jackson-jsonb-compat/src/test/java/io/smallrye/graphql/jackson/jsonb/JsonbAnnotationIntrospectorTest.java +++ b/common/jackson-jsonb-compat/src/test/java/io/smallrye/graphql/jackson/jsonb/JsonbAnnotationIntrospectorTest.java @@ -16,14 +16,14 @@ import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; class JsonbAnnotationIntrospectorTest { - private final ObjectMapper mapper = new ObjectMapper() - .registerModule(new JsonbCompatModule()) - .registerModule(new JavaTimeModule()); + private final ObjectMapper mapper = JsonMapper.builder() + .addModule(new JsonbCompatModule()) + .build(); // -- @JsonbProperty -- @@ -130,9 +130,10 @@ static class NumberFormatBean { @Test void jsonbNumberFormatSerializesWithPattern() throws Exception { - ObjectMapper usMapper = new ObjectMapper() - .registerModule(new JsonbCompatModule()) - .setLocale(Locale.US); + ObjectMapper usMapper = JsonMapper.builder() + .addModule(new JsonbCompatModule()) + .defaultLocale(Locale.US) + .build(); String json = usMapper.writeValueAsString(new NumberFormatBean()); assertThat(json).contains("\"1,234.50\""); } diff --git a/common/schema-builder/pom.xml b/common/schema-builder/pom.xml index c1081c65a..153e0d3f5 100644 --- a/common/schema-builder/pom.xml +++ b/common/schema-builder/pom.xml @@ -56,7 +56,7 @@ junit-jupiter - com.fasterxml.jackson.core + tools.jackson.core jackson-databind test diff --git a/common/schema-builder/src/main/java/io/smallrye/graphql/schema/Annotations.java b/common/schema-builder/src/main/java/io/smallrye/graphql/schema/Annotations.java index 96ea84b9b..e513951c2 100644 --- a/common/schema-builder/src/main/java/io/smallrye/graphql/schema/Annotations.java +++ b/common/schema-builder/src/main/java/io/smallrye/graphql/schema/Annotations.java @@ -642,9 +642,9 @@ private static Map getAnnotationsWithFilter(org.jbo public static final DotName JACKSON_CREATOR = DotName.createSimple("com.fasterxml.jackson.annotation.JsonCreator"); public static final DotName JACKSON_FORMAT = DotName.createSimple("com.fasterxml.jackson.annotation.JsonFormat"); public static final DotName JACKSON_SERIALIZE = DotName - .createSimple("com.fasterxml.jackson.databind.annotation.JsonSerialize"); + .createSimple("tools.jackson.databind.annotation.JsonSerialize"); public static final DotName JACKSON_DESERIALIZE = DotName - .createSimple("com.fasterxml.jackson.databind.annotation.JsonDeserialize"); + .createSimple("tools.jackson.databind.annotation.JsonDeserialize"); // Bean Validation Annotations (SmallRye extra, not part of the spec) public static final DotName JAVAX_BEAN_VALIDATION_NOT_NULL = DotName.createSimple("javax.validation.constraints.NotNull"); diff --git a/common/schema-builder/src/main/java/io/smallrye/graphql/schema/helper/AdaptWithHelper.java b/common/schema-builder/src/main/java/io/smallrye/graphql/schema/helper/AdaptWithHelper.java index 7a2df4311..527f5edb8 100644 --- a/common/schema-builder/src/main/java/io/smallrye/graphql/schema/helper/AdaptWithHelper.java +++ b/common/schema-builder/src/main/java/io/smallrye/graphql/schema/helper/AdaptWithHelper.java @@ -161,7 +161,7 @@ private static AdapterType getAdapterType(Annotations annotations) { AnnotationValue converterValue = serializeAnn.value("converter"); if (converterValue != null) { AdaptWith adaptWith = new AdaptWith( - "com.fasterxml.jackson.databind.util.StdConverter", + "tools.jackson.databind.util.StdConverter", "convert", "convert"); Type type = converterValue.asClass(); return new AdapterType(type, adaptWith); diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/index/SchemaBuilderTest.java b/common/schema-builder/src/test/java/io/smallrye/graphql/index/SchemaBuilderTest.java index 46b520450..601915f05 100644 --- a/common/schema-builder/src/test/java/io/smallrye/graphql/index/SchemaBuilderTest.java +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/index/SchemaBuilderTest.java @@ -30,10 +30,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - import io.smallrye.graphql.index.app.SomeDirective; import io.smallrye.graphql.schema.SchemaBuilder; import io.smallrye.graphql.schema.SchemaBuilderException; @@ -45,6 +41,10 @@ import io.smallrye.graphql.schema.model.Reference; import io.smallrye.graphql.schema.model.Schema; import io.smallrye.graphql.schema.model.Type; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.json.JsonMapper; /** * Test the model creation @@ -52,7 +52,7 @@ * @author Phillip Kruger (phillip.kruger@redhat.com) */ public class SchemaBuilderTest { - private static final ObjectMapper MAPPER = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + private static final ObjectMapper MAPPER = JsonMapper.builder().enable(SerializationFeature.INDENT_OUTPUT).build(); @Test public void testSchemaModelCreation() { @@ -65,7 +65,7 @@ public void testSchemaModelCreation() { private static String toJson(Object obj) { try { return MAPPER.writeValueAsString(obj); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } } diff --git a/common/schema-model/src/main/java/io/smallrye/graphql/schema/model/Scalars.java b/common/schema-model/src/main/java/io/smallrye/graphql/schema/model/Scalars.java index 9b1a024cb..fb6e8ba85 100644 --- a/common/schema-model/src/main/java/io/smallrye/graphql/schema/model/Scalars.java +++ b/common/schema-model/src/main/java/io/smallrye/graphql/schema/model/Scalars.java @@ -123,8 +123,8 @@ public static void addObject() { public static void addJson() { populateScalar("jakarta.json.JsonValue", JSON, Object.class.getName()); populateScalar("jakarta.json.JsonObject", JSON, Object.class.getName()); - populateScalar("com.fasterxml.jackson.databind.JsonNode", JSON, Object.class.getName()); - populateScalar("com.fasterxml.jackson.databind.node.ObjectNode", JSON, Object.class.getName()); + populateScalar("tools.jackson.databind.JsonNode", JSON, Object.class.getName()); + populateScalar("tools.jackson.databind.node.ObjectNode", JSON, Object.class.getName()); } static { diff --git a/docs/pom.xml b/docs/pom.xml index 65ae1fbbc..38442e604 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -55,7 +55,7 @@ jakarta.enterprise.cdi-api - com.fasterxml.jackson.core + tools.jackson.core jackson-databind diff --git a/docs/snippets/examples/dynamicclient/MyClientUsage.java b/docs/snippets/examples/dynamicclient/MyClientUsage.java index fcb9f1269..1647626af 100644 --- a/docs/snippets/examples/dynamicclient/MyClientUsage.java +++ b/docs/snippets/examples/dynamicclient/MyClientUsage.java @@ -7,7 +7,7 @@ import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import jakarta.inject.Inject; -import com.fasterxml.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ArrayNode; import java.util.List; import java.util.concurrent.ExecutionException; diff --git a/pom.xml b/pom.xml index c64988dd9..ad616e4f0 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ 9.1.0.Final 4.0.2 2.2.21 - 2.21.3 + 3.1.4 5.7.1 5.23.0 5.1.0.Final @@ -383,7 +383,7 @@ test - com.fasterxml.jackson + tools.jackson jackson-bom ${version.jackson} import diff --git a/server/implementation-cdi/src/test/java/io/smallrye/graphql/execution/CdiExecutionTest.java b/server/implementation-cdi/src/test/java/io/smallrye/graphql/execution/CdiExecutionTest.java index b7c05e303..8b8aa0b69 100644 --- a/server/implementation-cdi/src/test/java/io/smallrye/graphql/execution/CdiExecutionTest.java +++ b/server/implementation-cdi/src/test/java/io/smallrye/graphql/execution/CdiExecutionTest.java @@ -22,13 +22,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.cdi.producer.GraphQLProducer; import io.smallrye.graphql.schema.SchemaBuilder; import io.smallrye.graphql.schema.model.Schema; import io.smallrye.graphql.spi.LookupService; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; /** * Test a basic query diff --git a/server/implementation-servlet/pom.xml b/server/implementation-servlet/pom.xml index 32d2d73dd..e2b68ec7f 100644 --- a/server/implementation-servlet/pom.xml +++ b/server/implementation-servlet/pom.xml @@ -63,7 +63,7 @@ provided - com.fasterxml.jackson.core + tools.jackson.core jackson-databind diff --git a/server/implementation-servlet/src/main/java/io/smallrye/graphql/servlet/HttpServletResponseWriter.java b/server/implementation-servlet/src/main/java/io/smallrye/graphql/servlet/HttpServletResponseWriter.java index b797ef979..5cfa88ec2 100644 --- a/server/implementation-servlet/src/main/java/io/smallrye/graphql/servlet/HttpServletResponseWriter.java +++ b/server/implementation-servlet/src/main/java/io/smallrye/graphql/servlet/HttpServletResponseWriter.java @@ -4,10 +4,10 @@ import jakarta.servlet.http.HttpServletResponse; -import com.fasterxml.jackson.databind.ObjectMapper; - import io.smallrye.graphql.execution.ExecutionResponse; import io.smallrye.graphql.execution.ExecutionResponseWriter; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * Writing the response to HTTP servlet @@ -16,7 +16,7 @@ */ public class HttpServletResponseWriter implements ExecutionResponseWriter { private static final String APPLICATION_JSON_UTF8 = "application/json;charset=UTF-8"; - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = JsonMapper.builder().build(); private final HttpServletResponse response; diff --git a/server/implementation/pom.xml b/server/implementation/pom.xml index 68f8dbb51..3f9b53df5 100644 --- a/server/implementation/pom.xml +++ b/server/implementation/pom.xml @@ -28,17 +28,9 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-databind - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - io.smallrye smallrye-graphql-jackson-jsonb-compat diff --git a/server/implementation/src/main/java/io/smallrye/graphql/bootstrap/Bootstrap.java b/server/implementation/src/main/java/io/smallrye/graphql/bootstrap/Bootstrap.java index 8850326ec..dd8a7423b 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/bootstrap/Bootstrap.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/bootstrap/Bootstrap.java @@ -23,8 +23,6 @@ import org.eclipse.microprofile.graphql.Name; import com.apollographql.federation.graphqljava.Federation; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import graphql.Scalars; import graphql.introspection.Introspection.DirectiveLocation; @@ -89,6 +87,9 @@ import io.smallrye.graphql.spi.ClassloadingService; import io.smallrye.graphql.spi.LookupService; import io.smallrye.graphql.spi.config.Config; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * Bootstrap MicroProfile GraphQL @@ -1179,7 +1180,7 @@ private Object sanitizeDefaultValue(Field field) { ObjectMapper objectMapper = JacksonCreator.getObjectMapper(deserType.getName()); try { return objectMapper.readValue(jsonString, deserType); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException("Failed to deserialize default value: " + jsonString, e); } } @@ -1248,7 +1249,7 @@ private Type getTypeForField(Field field) { private static final String COMMA = ","; - private static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper JSON_OBJECT_MAPPER = JsonMapper.builder().build(); private static final String CONTEXT = "io.smallrye.graphql.api.Context"; private static final String OBSERVES = "javax.enterprise.event.Observes"; diff --git a/server/implementation/src/main/java/io/smallrye/graphql/execution/ExecutionResponse.java b/server/implementation/src/main/java/io/smallrye/graphql/execution/ExecutionResponse.java index 1e8737f5d..f65d36f5a 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/execution/ExecutionResponse.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/execution/ExecutionResponse.java @@ -16,20 +16,21 @@ import jakarta.json.spi.JsonProvider; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.NullNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import graphql.ExecutionResult; import graphql.GraphQLError; import io.smallrye.graphql.execution.error.ExecutionErrorsService; import io.smallrye.graphql.spi.config.Config; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.NullNode; +import tools.jackson.databind.node.ObjectNode; /** * Response from an execution @@ -99,7 +100,7 @@ public JsonObject getExecutionResultAsJsonPObject() { public String getExecutionResultAsString() { try { return OBJECT_MAPPER.writeValueAsString(getExecutionResultAsJsonObject()); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new RuntimeException(e); } } @@ -287,7 +288,7 @@ private static JsonNode excludeNullFields(JsonNode jsonNode) { if (jsonNode instanceof ObjectNode) { ObjectNode objectNode = (ObjectNode) jsonNode; ObjectNode result = NODE_FACTORY.objectNode(); - objectNode.fields().forEachRemaining(entry -> { + objectNode.properties().forEach(entry -> { if (entry.getValue() != null && !entry.getValue().isNull()) { result.set(entry.getKey(), excludeNullFields(entry.getValue())); } @@ -306,11 +307,12 @@ private static JsonNode excludeNullFields(JsonNode jsonNode) { } private static ObjectMapper createObjectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); - mapper.disable(SerializationFeature.INDENT_OUTPUT); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return mapper; + return JsonMapper.builder() + .disable(SerializationFeature.INDENT_OUTPUT) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .changeDefaultPropertyInclusion(v -> JsonInclude.Value.construct(JsonInclude.Include.ALWAYS, + JsonInclude.Include.ALWAYS)) + .build(); } private static final String DATA = "data"; diff --git a/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/DataFetcherException.java b/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/DataFetcherException.java index 9ce8508b8..432446a24 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/DataFetcherException.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/DataFetcherException.java @@ -1,10 +1,10 @@ package io.smallrye.graphql.execution.datafetcher; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - import io.smallrye.graphql.schema.model.Operation; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.json.JsonMapper; /** * There was an issue when fetching data. @@ -12,8 +12,9 @@ * @author Phillip Kruger (phillip.kruger@redhat.com) */ public class DataFetcherException extends RuntimeException { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() - .enable(SerializationFeature.INDENT_OUTPUT); + private static final ObjectMapper OBJECT_MAPPER = JsonMapper.builder() + .enable(SerializationFeature.INDENT_OUTPUT) + .build(); public DataFetcherException() { } @@ -29,7 +30,7 @@ public DataFetcherException(Operation operation, Exception ex) { private static String toJson(Operation operation) { try { return OBJECT_MAPPER.writeValueAsString(operation); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { return operation.toString(); } } diff --git a/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/ArgumentHelper.java b/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/ArgumentHelper.java index 67bb6d0e0..bb4417e80 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/ArgumentHelper.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/ArgumentHelper.java @@ -17,9 +17,6 @@ import java.util.Optional; import java.util.Set; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import graphql.schema.DataFetchingEnvironment; import graphql.schema.GraphQLScalarType; import io.smallrye.graphql.execution.Classes; @@ -34,6 +31,8 @@ import io.smallrye.graphql.transformation.AbstractDataFetcherException; import io.smallrye.graphql.transformation.TransformException; import io.smallrye.graphql.transformation.Transformer; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; /** * Help with the arguments when doing reflection calls @@ -369,9 +368,9 @@ && isJacksonJsonNodeType(field.getReference().getClassName())) { * @return a java object of this type. */ private static boolean isJacksonJsonNodeType(String className) { - return "com.fasterxml.jackson.databind.JsonNode".equals(className) - || "com.fasterxml.jackson.databind.node.ObjectNode".equals(className) - || "com.fasterxml.jackson.databind.node.ArrayNode".equals(className); + return "tools.jackson.databind.JsonNode".equals(className) + || "tools.jackson.databind.node.ObjectNode".equals(className) + || "tools.jackson.databind.node.ArrayNode".equals(className); } private Object correctComplexObjectFromMap(Map m, Field field, DataFetchingEnvironment dfe) @@ -458,7 +457,7 @@ private Object correctComplexObjectFromMap(Map m, Field field, DataFetchingEnvir } return result; - } catch (JsonProcessingException e) { + } catch (JacksonException e) { throw new TransformException(e, field, m); } } @@ -523,7 +522,7 @@ private Object correctComplexObjectFromJsonString(String jsonString, Field field try { ObjectMapper objectMapper = JacksonCreator.getObjectMapper(className); return objectMapper.readValue(jsonString, objectMapper.constructType(type)); - } catch (JsonProcessingException jpe) { + } catch (JacksonException jpe) { throw new TransformException(jpe, field, jsonString); } } diff --git a/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/DefaultMapAdapter.java b/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/DefaultMapAdapter.java index 55519e079..c87038935 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/DefaultMapAdapter.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/execution/datafetcher/helper/DefaultMapAdapter.java @@ -6,9 +6,6 @@ import java.util.Map; import java.util.Set; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - import io.smallrye.graphql.api.Entry; import io.smallrye.graphql.json.JacksonCreator; import io.smallrye.graphql.schema.model.Field; @@ -17,6 +14,8 @@ import io.smallrye.graphql.schema.model.Wrapper; import io.smallrye.graphql.schema.model.WrapperType; import io.smallrye.graphql.spi.ClassloadingService; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; /** * The adapter to change map to Entry Set.Users can also supply their own adapter. @@ -80,7 +79,7 @@ private T toObject(Reference reference, T t) { ObjectMapper objectMapper = JacksonCreator.getObjectMapper(className); Class clazz = classloadingService.loadClass(className); return (T) objectMapper.readValue(jsonString, clazz); - } catch (JsonProcessingException jpe) { + } catch (JacksonException jpe) { throw new RuntimeException(jpe); } } diff --git a/server/implementation/src/main/java/io/smallrye/graphql/execution/error/ExecutionErrorsService.java b/server/implementation/src/main/java/io/smallrye/graphql/execution/error/ExecutionErrorsService.java index 1d074ec64..53e0e0d1d 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/execution/error/ExecutionErrorsService.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/execution/error/ExecutionErrorsService.java @@ -6,16 +6,16 @@ import jakarta.json.JsonValue; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; - import graphql.ExceptionWhileDataFetching; import graphql.GraphQLError; import graphql.validation.ValidationError; import io.smallrye.graphql.spi.config.Config; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; +import tools.jackson.databind.node.ObjectNode; /** * Help to create the exceptions @@ -25,7 +25,7 @@ public class ExecutionErrorsService { private static final JsonNodeFactory NODE_FACTORY = JsonNodeFactory.instance; - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = JsonMapper.builder().build(); private final ErrorExtensionProviders errorExtensionProviders = new ErrorExtensionProviders(); diff --git a/server/implementation/src/main/java/io/smallrye/graphql/execution/event/EventEmitter.java b/server/implementation/src/main/java/io/smallrye/graphql/execution/event/EventEmitter.java index 57a17f7b8..6b959ea6a 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/execution/event/EventEmitter.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/execution/event/EventEmitter.java @@ -13,14 +13,13 @@ import org.jboss.logging.Logger; -import com.fasterxml.jackson.databind.ObjectMapper; - import graphql.GraphQL; import graphql.schema.GraphQLSchema; import io.smallrye.graphql.api.Context; import io.smallrye.graphql.schema.model.Operation; import io.smallrye.graphql.spi.EventingService; import io.smallrye.graphql.spi.config.Config; +import tools.jackson.databind.ObjectMapper; /** * Fire some events while booting or executing. diff --git a/server/implementation/src/main/java/io/smallrye/graphql/json/GraphQLNamingStrategy.java b/server/implementation/src/main/java/io/smallrye/graphql/json/GraphQLNamingStrategy.java index 10e1ce246..2dce4a768 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/json/GraphQLNamingStrategy.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/json/GraphQLNamingStrategy.java @@ -2,7 +2,7 @@ import java.util.Map; -import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import tools.jackson.databind.PropertyNamingStrategies; /** * Naming strategy that takes GraphQL annotations into account diff --git a/server/implementation/src/main/java/io/smallrye/graphql/json/JacksonCreator.java b/server/implementation/src/main/java/io/smallrye/graphql/json/JacksonCreator.java index a9763b226..7c3115800 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/json/JacksonCreator.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/json/JacksonCreator.java @@ -1,31 +1,11 @@ package io.smallrye.graphql.json; -import java.io.IOException; import java.math.BigDecimal; import java.util.Collection; import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.BeanDescription; -import com.fasterxml.jackson.databind.DeserializationConfig; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.KeyDeserializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.deser.KeyDeserializers; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.smallrye.graphql.api.CustomFloatScalar; import io.smallrye.graphql.api.CustomIntScalar; @@ -34,6 +14,23 @@ import io.smallrye.graphql.schema.model.Field; import io.smallrye.graphql.schema.model.InputType; import io.smallrye.graphql.spi.ClassloadingService; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.BeanDescription; +import tools.jackson.databind.DeserializationConfig; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.JavaType; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.KeyDeserializer; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.SerializationFeature; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.ValueSerializer; +import tools.jackson.databind.deser.KeyDeserializers; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.module.SimpleModule; /** * Here we create ObjectMapper instances for certain input objects. @@ -87,40 +84,39 @@ public static ObjectMapper getObjectMapper() { } private static ObjectMapper createObjectMapper(Map customFieldNameMapping) { - ObjectMapper mapper = createDefaultObjectMapper(); - mapper.setPropertyNamingStrategy(new GraphQLNamingStrategy(customFieldNameMapping)); - return mapper; + return defaultMapperBuilder() + .propertyNamingStrategy(new GraphQLNamingStrategy(customFieldNameMapping)) + .build(); } private static ObjectMapper createDefaultObjectMapper() { - ObjectMapper mapper = new ObjectMapper(); - mapper.registerModule(new JsonbCompatModule()); - mapper.registerModule(new JavaTimeModule()); - mapper.registerModule(new Jdk8Module()); - mapper.registerModule(CUSTOM_SCALARS_MODULE); - mapper.registerModule(createComplexKeyModule()); - mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); - mapper.enable(SerializationFeature.INDENT_OUTPUT); - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - // Include null values in serialization (required by @JsonbCreator / Jackson creator methods) - mapper.setDefaultPropertyInclusion(JsonInclude.Include.ALWAYS); - return mapper; + return defaultMapperBuilder().build(); + } + + private static JsonMapper.Builder defaultMapperBuilder() { + return JsonMapper.builder() + .addModule(new JsonbCompatModule()) + .addModule(CUSTOM_SCALARS_MODULE) + .addModule(createComplexKeyModule()) + .enable(SerializationFeature.INDENT_OUTPUT) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .changeDefaultPropertyInclusion(v -> JsonInclude.Value.construct(JsonInclude.Include.ALWAYS, + JsonInclude.Include.ALWAYS)); } private static SimpleModule createCustomScalarsModule() { SimpleModule module = new SimpleModule("CustomScalars"); // CustomStringScalar serializer/deserializer - module.addSerializer(CustomStringScalar.class, new JsonSerializer() { + module.addSerializer(CustomStringScalar.class, new ValueSerializer() { @Override - public void serialize(CustomStringScalar value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { + public void serialize(CustomStringScalar value, JsonGenerator gen, SerializationContext serializers) { gen.writeString(value.stringValueForSerialization()); } }); - module.addDeserializer(CustomStringScalar.class, new JsonDeserializer() { + module.addDeserializer(CustomStringScalar.class, new ValueDeserializer() { @Override - public CustomStringScalar deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public CustomStringScalar deserialize(JsonParser p, DeserializationContext ctxt) { JsonNode node = p.readValueAsTree(); if (node == null || node.isNull()) { return null; @@ -141,16 +137,15 @@ public CustomStringScalar deserialize(JsonParser p, DeserializationContext ctxt) }); // CustomIntScalar serializer/deserializer - module.addSerializer(CustomIntScalar.class, new JsonSerializer() { + module.addSerializer(CustomIntScalar.class, new ValueSerializer() { @Override - public void serialize(CustomIntScalar value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { + public void serialize(CustomIntScalar value, JsonGenerator gen, SerializationContext serializers) { gen.writeNumber(value.intValueForSerialization()); } }); - module.addDeserializer(CustomIntScalar.class, new JsonDeserializer() { + module.addDeserializer(CustomIntScalar.class, new ValueDeserializer() { @Override - public CustomIntScalar deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public CustomIntScalar deserialize(JsonParser p, DeserializationContext ctxt) { JsonNode node = p.readValueAsTree(); if (node == null || node.isNull()) { return null; @@ -171,16 +166,15 @@ public CustomIntScalar deserialize(JsonParser p, DeserializationContext ctxt) th }); // CustomFloatScalar serializer/deserializer - module.addSerializer(CustomFloatScalar.class, new JsonSerializer() { + module.addSerializer(CustomFloatScalar.class, new ValueSerializer() { @Override - public void serialize(CustomFloatScalar value, JsonGenerator gen, SerializerProvider serializers) - throws IOException { + public void serialize(CustomFloatScalar value, JsonGenerator gen, SerializationContext serializers) { gen.writeNumber(value.floatValueForSerialization()); } }); - module.addDeserializer(CustomFloatScalar.class, new JsonDeserializer() { + module.addDeserializer(CustomFloatScalar.class, new ValueDeserializer() { @Override - public CustomFloatScalar deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public CustomFloatScalar deserialize(JsonParser p, DeserializationContext ctxt) { JsonNode node = p.readValueAsTree(); if (node == null || node.isNull()) { return null; @@ -201,27 +195,27 @@ public CustomFloatScalar deserialize(JsonParser p, DeserializationContext ctxt) }); // jakarta.json.JsonObject deserializer — needed for JSON scalar type support - module.addDeserializer(jakarta.json.JsonObject.class, new JsonDeserializer() { + module.addDeserializer(jakarta.json.JsonObject.class, new ValueDeserializer() { @Override - public jakarta.json.JsonObject deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public jakarta.json.JsonObject deserialize(JsonParser p, DeserializationContext ctxt) { JsonNode node = p.readValueAsTree(); return (jakarta.json.JsonObject) jacksonNodeToJsonPValue(node); } }); // jakarta.json.JsonArray deserializer - module.addDeserializer(jakarta.json.JsonArray.class, new JsonDeserializer() { + module.addDeserializer(jakarta.json.JsonArray.class, new ValueDeserializer() { @Override - public jakarta.json.JsonArray deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public jakarta.json.JsonArray deserialize(JsonParser p, DeserializationContext ctxt) { JsonNode node = p.readValueAsTree(); return (jakarta.json.JsonArray) jacksonNodeToJsonPValue(node); } }); // jakarta.json.JsonValue deserializer - module.addDeserializer(jakarta.json.JsonValue.class, new JsonDeserializer() { + module.addDeserializer(jakarta.json.JsonValue.class, new ValueDeserializer() { @Override - public jakarta.json.JsonValue deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + public jakarta.json.JsonValue deserialize(JsonParser p, DeserializationContext ctxt) { JsonNode node = p.readValueAsTree(); return jacksonNodeToJsonPValue(node); } @@ -230,16 +224,16 @@ public jakarta.json.JsonValue deserialize(JsonParser p, DeserializationContext c return module; } - private static com.fasterxml.jackson.databind.Module createComplexKeyModule() { - return new com.fasterxml.jackson.databind.Module() { + private static tools.jackson.databind.JacksonModule createComplexKeyModule() { + return new tools.jackson.databind.JacksonModule() { @Override public String getModuleName() { return "ComplexMapKeys"; } @Override - public com.fasterxml.jackson.core.Version version() { - return com.fasterxml.jackson.core.Version.unknownVersion(); + public tools.jackson.core.Version version() { + return tools.jackson.core.Version.unknownVersion(); } @Override @@ -247,16 +241,17 @@ public void setupModule(SetupContext context) { context.addKeyDeserializers(new KeyDeserializers() { @Override public KeyDeserializer findKeyDeserializer(JavaType keyType, DeserializationConfig config, - BeanDescription beanDesc) throws JsonMappingException { + BeanDescription.Supplier beanDescSupplier) { Class raw = keyType.getRawClass(); if (!isComplexKeyType(raw)) { return null; } return new KeyDeserializer() { @Override - public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException { - ObjectMapper mapper = (ObjectMapper) ctxt.getParser().getCodec(); - return mapper.readValue(key, keyType); + public Object deserializeKey(String key, DeserializationContext ctxt) { + try (JsonParser parser = ctxt.tokenStreamFactory().createParser(key)) { + return ctxt.readValue(parser, keyType); + } } }; } @@ -271,7 +266,8 @@ private static boolean isComplexKeyType(Class type) { } String name = type.getName(); return !name.startsWith("java.") && !name.startsWith("javax.") - && !name.startsWith("jakarta.") && !name.startsWith("com.fasterxml."); + && !name.startsWith("jakarta.") && !name.startsWith("com.fasterxml.") + && !name.startsWith("tools.jackson."); } private static jakarta.json.JsonValue jacksonNodeToJsonPValue(JsonNode node) { @@ -280,7 +276,7 @@ private static jakarta.json.JsonValue jacksonNodeToJsonPValue(JsonNode node) { } if (node.isObject()) { jakarta.json.JsonObjectBuilder builder = jakarta.json.Json.createObjectBuilder(); - node.fields().forEachRemaining(entry -> builder.add(entry.getKey(), jacksonNodeToJsonPValue(entry.getValue()))); + node.properties().forEach(entry -> builder.add(entry.getKey(), jacksonNodeToJsonPValue(entry.getValue()))); return builder.build(); } if (node.isArray()) { diff --git a/server/implementation/src/main/java/io/smallrye/graphql/json/JsonInputRegistry.java b/server/implementation/src/main/java/io/smallrye/graphql/json/JsonInputRegistry.java index 68710611a..ca745a0d3 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/json/JsonInputRegistry.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/json/JsonInputRegistry.java @@ -2,9 +2,8 @@ import java.util.Map; -import com.fasterxml.jackson.databind.ObjectMapper; - import io.smallrye.graphql.schema.model.InputType; +import tools.jackson.databind.ObjectMapper; /** * Here we register input objects to be used when creating method calls diff --git a/server/implementation/src/main/java/io/smallrye/graphql/scalar/GraphQLScalarTypes.java b/server/implementation/src/main/java/io/smallrye/graphql/scalar/GraphQLScalarTypes.java index e8841b66b..56de786cb 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/scalar/GraphQLScalarTypes.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/scalar/GraphQLScalarTypes.java @@ -63,8 +63,8 @@ public static void addObject() { public static void addJson() { SCALAR_MAP.put(Object.class.getName(), ExtendedScalars.Json); - SCALAR_MAP.put("com.fasterxml.jackson.databind.JsonNode", ExtendedScalars.Json); - SCALAR_MAP.put("com.fasterxml.jackson.databind.node.ObjectNode", ExtendedScalars.Json); + SCALAR_MAP.put("tools.jackson.databind.JsonNode", ExtendedScalars.Json); + SCALAR_MAP.put("tools.jackson.databind.node.ObjectNode", ExtendedScalars.Json); SCALARS_BY_NAME.put(ExtendedScalars.Json.getName(), ExtendedScalars.Json); } diff --git a/server/implementation/src/main/java/io/smallrye/graphql/spi/EventingService.java b/server/implementation/src/main/java/io/smallrye/graphql/spi/EventingService.java index dcb67f8f7..43908bf5c 100644 --- a/server/implementation/src/main/java/io/smallrye/graphql/spi/EventingService.java +++ b/server/implementation/src/main/java/io/smallrye/graphql/spi/EventingService.java @@ -3,13 +3,12 @@ import java.util.Collections; import java.util.Map; -import com.fasterxml.jackson.databind.ObjectMapper; - import graphql.GraphQL; import graphql.schema.GraphQLSchema; import io.smallrye.graphql.api.Context; import io.smallrye.graphql.execution.event.InvokeInfo; import io.smallrye.graphql.schema.model.Operation; +import tools.jackson.databind.ObjectMapper; /** * Some events during bootstrap and execution that allows extension diff --git a/server/implementation/src/test/java/io/smallrye/graphql/execution/error/ExecutionErrorsServiceTest.java b/server/implementation/src/test/java/io/smallrye/graphql/execution/error/ExecutionErrorsServiceTest.java index 2f9db34c6..97055a7f8 100644 --- a/server/implementation/src/test/java/io/smallrye/graphql/execution/error/ExecutionErrorsServiceTest.java +++ b/server/implementation/src/test/java/io/smallrye/graphql/execution/error/ExecutionErrorsServiceTest.java @@ -10,9 +10,6 @@ import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import graphql.ExceptionWhileDataFetching; import graphql.GraphQLError; import graphql.GraphqlErrorException; @@ -21,6 +18,8 @@ import graphql.validation.ValidationError; import graphql.validation.ValidationErrorType; import io.smallrye.graphql.spi.config.Config; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; /** * Test for {@link ExecutionErrorsService} diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/DynamicClientInjectionTest.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/DynamicClientInjectionTest.java index 16ffade01..412b0ccb1 100644 --- a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/DynamicClientInjectionTest.java +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/DynamicClientInjectionTest.java @@ -14,13 +14,12 @@ import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.GraphQLClient; import io.smallrye.graphql.client.core.Document; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClient; import io.vertx.core.MultiMap; +import tools.jackson.databind.node.ObjectNode; /** * Verify a named dynamic client injected via CDI and configured via MP Config properties diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/DynamicClientSingleOperationsTestBase.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/DynamicClientSingleOperationsTestBase.java index aea156eed..673a57ef2 100644 --- a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/DynamicClientSingleOperationsTestBase.java +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/DynamicClientSingleOperationsTestBase.java @@ -23,13 +23,12 @@ import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.core.Document; import io.smallrye.graphql.client.core.ScalarType; import io.smallrye.graphql.client.core.Variable; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClient; +import tools.jackson.databind.node.ObjectNode; public abstract class DynamicClientSingleOperationsTestBase { diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/NestedRecordsTest.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/NestedRecordsTest.java index 74c28215d..da7c5f370 100644 --- a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/NestedRecordsTest.java +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/NestedRecordsTest.java @@ -28,14 +28,13 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.core.Document; import io.smallrye.graphql.client.core.InputObject; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClientBuilder; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; @ExtendWith(ArquillianExtension.class) @RunAsClient diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/RecordTest.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/RecordTest.java index 3213fbc25..944b1413e 100644 --- a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/RecordTest.java +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/RecordTest.java @@ -26,13 +26,13 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.core.Document; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClientBuilder; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; /** * This test verifies that the server side can handle Java records in GraphQL apis, both as input and as output types. diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/extensions/DynamicClientInboundExtensionsTest.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/extensions/DynamicClientInboundExtensionsTest.java index 0850de36c..b1a46d65a 100644 --- a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/extensions/DynamicClientInboundExtensionsTest.java +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/extensions/DynamicClientInboundExtensionsTest.java @@ -25,13 +25,13 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClient; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClientBuilder; import io.smallrye.graphql.execution.context.SmallRyeContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; /** * Test extension(s) features of the dynamic client @@ -72,7 +72,7 @@ public void addedExtensionsTest() throws Exception { field("poolWithExtensions", field("volume"))))); // Compare structurally by converting both to JsonNode through a common JSON round-trip - ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = JsonMapper.builder().build(); JsonNode expected = mapper.readTree(mapper.writeValueAsString(getMap())); JsonNode actual = mapper.readTree(response.getExtensions().toString()); assertEquals(expected, actual); diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/fragments/DynamicClientFragmentTest.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/fragments/DynamicClientFragmentTest.java index 5a044fcde..c352ec840 100644 --- a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/fragments/DynamicClientFragmentTest.java +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/client/dynamic/fragments/DynamicClientFragmentTest.java @@ -24,13 +24,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.core.Document; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClient; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClientBuilder; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; @ExtendWith(ArquillianExtension.class) @RunAsClient diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/json/CustomJsonbService.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/json/CustomJsonbService.java index 54ee640c9..1014e8a6e 100644 --- a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/json/CustomJsonbService.java +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/json/CustomJsonbService.java @@ -4,9 +4,9 @@ import java.util.Collections; import java.util.Map; -import com.fasterxml.jackson.databind.ObjectMapper; - import io.smallrye.graphql.spi.EventingService; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; public class CustomJsonbService implements EventingService { @@ -17,8 +17,9 @@ public String getConfigKey() { @Override public Map overrideObjectMapperConfig() { - ObjectMapper mapper = new ObjectMapper(); - mapper.setDateFormat(new SimpleDateFormat("MM dd yyyy HH:mm Z")); + ObjectMapper mapper = JsonMapper.builder() + .defaultDateFormat(new SimpleDateFormat("MM dd yyyy HH:mm Z")) + .build(); return Collections.singletonMap(DateWrapper.class.getName(), mapper); } } diff --git a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/subscription/SubscriptionFieldBatchingTest.java b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/subscription/SubscriptionFieldBatchingTest.java index 72681d8db..f583b0dd3 100644 --- a/server/integration-tests/src/test/java/io/smallrye/graphql/tests/subscription/SubscriptionFieldBatchingTest.java +++ b/server/integration-tests/src/test/java/io/smallrye/graphql/tests/subscription/SubscriptionFieldBatchingTest.java @@ -16,13 +16,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import com.fasterxml.jackson.databind.node.ObjectNode; - import io.smallrye.graphql.api.Subscription; import io.smallrye.graphql.client.Response; import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient; import io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClientBuilder; import io.smallrye.mutiny.Multi; +import tools.jackson.databind.node.ObjectNode; @ExtendWith(ArquillianExtension.class) public class SubscriptionFieldBatchingTest { diff --git a/server/tck/pom.xml b/server/tck/pom.xml index 5c8f7b29d..24ee5ae91 100644 --- a/server/tck/pom.xml +++ b/server/tck/pom.xml @@ -89,7 +89,7 @@ - com.fasterxml.jackson.core + tools.jackson.core jackson-core test From 33c49f53e63e68d52ed548022e53f892ca3d2cc3 Mon Sep 17 00:00:00 2001 From: Phillip Kruger Date: Tue, 7 Jul 2026 10:35:55 +1000 Subject: [PATCH 2/2] Fix malformed JSON in client TCK error tests for Jackson 3 Jackson 3 enforces FAIL_ON_TRAILING_TOKENS by default, unlike Jackson 2 which silently ignored trailing content after the root JSON value. Several test JSON strings had an extra trailing } brace that was previously masked by Jackson 2's lenient parsing. --- .../tck/graphql/typesafe/ErrorBehavior.java | 18 +++++++++--------- .../typesafe/TypesafeResponseBehavior.java | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/client/tck/src/main/java/tck/graphql/typesafe/ErrorBehavior.java b/client/tck/src/main/java/tck/graphql/typesafe/ErrorBehavior.java index ac656854e..b23d6c05d 100644 --- a/client/tck/src/main/java/tck/graphql/typesafe/ErrorBehavior.java +++ b/client/tck/src/main/java/tck/graphql/typesafe/ErrorBehavior.java @@ -39,7 +39,7 @@ void shouldFailOnQueryError() { /**//**/"\"queryPath\":[\"greeting\"]," + /**//**/"\"classification\":\"DataFetchingException\"," + /**//**/"\"code\":\"no-greeting\"}" + - "}]}}"); + "}]}"); StringApi api = fixture.build(StringApi.class); GraphQLClientException thrown = catchThrowableOfType(api::greeting, GraphQLClientException.class); @@ -101,7 +101,7 @@ void shouldFailOnErrorWithoutMessage() { /**//**/"\"queryPath\":[\"greeting\"]," + /**//**/"\"classification\":\"DataFetchingException\"," + /**//**/"\"code\":\"no-greeting\"}" + - "}]}}"); + "}]}"); StringApi api = fixture.build(StringApi.class); GraphQLClientException thrown = catchThrowableOfType(api::greeting, GraphQLClientException.class); @@ -287,7 +287,7 @@ void shouldFetchErrorOrAbsent() { /**//**/"\"queryPath\":[\"foo\"]," + /**//**/"\"classification\":\"ValidationError\"," + /**//**/"\"code\":\"team-search-disabled\"}" + - "}]}}"); + "}]}"); SuperHeroApi api = fixture.build(SuperHeroApi.class); ErrorOr> response = api.teams(); @@ -314,7 +314,7 @@ void shouldFetchErrorOnNullData() { /**//**/"\"queryPath\":[\"foo\"]," + /**//**/"\"classification\":\"ValidationError\"," + /**//**/"\"code\":\"team-search-disabled\"}" + - "}]}}"); + "}]}"); SuperHeroApi api = fixture.build(SuperHeroApi.class); GraphQLClientException throwable = catchThrowableOfType(api::teams, GraphQLClientException.class); @@ -349,7 +349,7 @@ void shouldFetchErrorOrWithTwoErrors() { /**//**/"\"description\":\"not feeling so well\"," + /**//**/"\"queryPath\":[\"bar\"]," + /**//**/"\"code\":\"dizzy\"}" + - "}]}}"); + "}]}"); SuperHeroApi api = fixture.build(SuperHeroApi.class); ErrorOr> response = api.teams(); @@ -383,7 +383,7 @@ void shouldFetchErrorOrAbsentWithoutPath() { /**//**/"\"queryPath\":[\"foo\"]," + /**//**/"\"classification\":\"ValidationError\"," + /**//**/"\"code\":\"team-search-disabled\"}" + - "}]}}"); + "}]}"); SuperHeroApi api = fixture.build(SuperHeroApi.class); GraphQLClientException throwable = catchThrowableOfType(api::teams, GraphQLClientException.class); @@ -406,7 +406,7 @@ void shouldFetchErrorOrWithNullInPath() { /**/"\"path\": [\"teams\",\"name\"],\n" + /**/"\"extensions\":{" + /**//**/"\"code\":\"team-name-disabled\"}" + - "}]}}"); + "}]}"); SuperHeroApi api = fixture.build(SuperHeroApi.class); GraphQLClientException throwable = catchThrowableOfType(api::teams, GraphQLClientException.class); @@ -471,7 +471,7 @@ void shouldFetchPartialWrapper() { /**/"\"locations\":[{\"line\":1,\"column\":2,\"sourceName\":\"loc\"}]," + /**/"\"path\": [\"find\",\"teams\"],\n" + /**/"\"extensions\":{\"code\":\"team-search-disabled\"}" + - "}]}}"); + "}]}"); SuperHeroWrappedApi api = fixture.build(SuperHeroWrappedApi.class); Wrapper response = api.find(); @@ -597,7 +597,7 @@ private String deeplyNestedError(String data) { /**/"\"locations\":[{\"line\":1,\"column\":2,\"sourceName\":\"loc\"}]," + /**/"\"path\": [\"outer\",\"inner\",\"content\"],\n" + /**/"\"extensions\":{\"code\":\"dummy-code\"}" + - "}]}}"; + "}]}"; } private void thenDeeplyNestedErrorException(GraphQLClientException throwable) { diff --git a/client/tck/src/main/java/tck/graphql/typesafe/TypesafeResponseBehavior.java b/client/tck/src/main/java/tck/graphql/typesafe/TypesafeResponseBehavior.java index 176149637..ea0bb8e17 100644 --- a/client/tck/src/main/java/tck/graphql/typesafe/TypesafeResponseBehavior.java +++ b/client/tck/src/main/java/tck/graphql/typesafe/TypesafeResponseBehavior.java @@ -76,7 +76,7 @@ void shouldHandleErrorsInTypesafeResponse() { /**//**/"\"queryPath\":[\"greeting\"]," + /**//**/"\"classification\":\"DataFetchingException\"," + /**//**/"\"code\":\"no-greetings\"}" + - "}]}}"); + "}]}"); StringApi api = fixture.build(StringApi.class); assertThrows(NoSuchElementException.class, () -> api.greetings().get()); GraphQLError error = api.greetings().getErrors().get(0);