From 26a5dbaf73350c4456c744240048874af7a4d91e Mon Sep 17 00:00:00 2001 From: Julius Lauterbach Date: Sat, 28 Mar 2026 00:58:07 +0100 Subject: [PATCH 1/8] refactor: update Jackson imports to use tools.jackson package Signed-off-by: Julius Lauterbach --- .../besu/response/BesuSignerMetric.java | 2 +- .../response/privacy/PrivateTransaction.java | 25 ++++----- .../privacy/PrivateTransactionLegacy.java | 6 +-- .../PrivateTransactionWithPrivacyGroup.java | 6 +-- build.gradle | 9 ++-- .../codegen/SolidityFunctionWrapper.java | 2 +- .../SolidityFunctionWrapperGenerator.java | 2 +- .../TruffleJsonFunctionWrapperGenerator.java | 4 +- core/build.gradle | 2 +- .../java/org/web3j/crypto/WalletFile.java | 24 ++++----- .../java/org/web3j/crypto/WalletUtils.java | 19 +++---- .../org/web3j/ens/EnsMetadataResponse.java | 6 +-- .../main/java/org/web3j/ens/EnsResolver.java | 9 ++-- .../web3j/protocol/ObjectMapperFactory.java | 54 +++++++++---------- .../main/java/org/web3j/protocol/Service.java | 4 +- .../java/org/web3j/protocol/core/Request.java | 2 + .../org/web3j/protocol/core/Response.java | 2 +- .../core/methods/request/Transaction.java | 2 + .../core/methods/response/EthBlock.java | 30 +++++------ .../response/EthEstimateUserOperationGas.java | 30 +++++------ .../core/methods/response/EthFeeHistory.java | 25 ++++----- .../core/methods/response/EthGetProof.java | 26 +++++---- .../response/EthGetTransactionReceipt.java | 24 ++++----- .../response/EthGetUserOperationByHash.java | 27 +++++----- .../response/EthGetUserOperationReceipt.java | 27 +++++----- .../core/methods/response/EthLog.java | 27 +++++----- .../core/methods/response/EthSyncing.java | 28 +++++----- .../core/methods/response/EthTransaction.java | 23 ++++---- .../methods/response/LineaEstimateGas.java | 29 +++++----- .../core/methods/response/LineaGetProof.java | 2 +- .../LineaGetTransactionExclusionStatusV1.java | 27 +++++----- .../methods/response/admin/AdminNodeInfo.java | 27 +++++----- .../methods/response/admin/AdminPeers.java | 30 +++++------ .../deserializer/KeepAsJsonDeserialzier.java | 17 +++--- .../deserializer/RawResponseDeserializer.java | 47 +++++++--------- .../protocol/websocket/WebSocketService.java | 21 ++++---- .../java/org/web3j/crypto/WalletFileTest.java | 2 +- .../java/org/web3j/crypto/WalletTest.java | 2 +- .../java/org/web3j/ens/EnsResolverTest.java | 6 +-- .../java/org/web3j/protocol/BatchTester.java | 2 +- .../protocol/core/WebSocketEventTest.java | 4 +- .../protocol/core/filters/FilterTester.java | 2 +- .../web3j/protocol/rx/JsonRpc2_0RxTest.java | 2 +- .../tx/HSMHTTPRequestProcessorTestImpl.java | 8 +-- .../web3j/tx/RawTransactionManagerTest.java | 2 +- crypto/build.gradle | 2 +- .../java/org/web3j/crypto/Secp256k1JWK.java | 4 +- .../web3j/crypto/StructuredDataEncoder.java | 6 +-- .../org/web3j/crypto/Secp256k1JWKTest.java | 2 +- .../org/web3j/crypto/StructuredDataTest.java | 2 +- .../java/org/web3j/utils/Base64String.java | 31 ++++++----- .../protocol/geth/JsonRpc2_0GethTest.java | 4 +- .../parity/methods/response/StateDiff.java | 2 +- .../parity/methods/response/Trace.java | 22 ++++---- 54 files changed, 351 insertions(+), 401 deletions(-) diff --git a/besu/src/main/java/org/web3j/protocol/besu/response/BesuSignerMetric.java b/besu/src/main/java/org/web3j/protocol/besu/response/BesuSignerMetric.java index 4779575214..36449e1332 100644 --- a/besu/src/main/java/org/web3j/protocol/besu/response/BesuSignerMetric.java +++ b/besu/src/main/java/org/web3j/protocol/besu/response/BesuSignerMetric.java @@ -30,7 +30,7 @@ public class BesuSignerMetric { public BesuSignerMetric( @JsonProperty(value = "address") final String address, @JsonProperty(value = "proposedBlockCount") final String proposedBlockCount, - @JsonProperty(value = "name") final String lastProposedBlockNumber) { + @JsonProperty(value = "lastProposedBlockNumber") final String lastProposedBlockNumber) { this.address = address; this.proposedBlockCount = proposedBlockCount; this.lastProposedBlockNumber = lastProposedBlockNumber; diff --git a/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransaction.java b/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransaction.java index 40ae11586e..dc6bf65814 100644 --- a/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransaction.java +++ b/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransaction.java @@ -12,15 +12,15 @@ */ package org.web3j.protocol.besu.response.privacy; -import java.io.IOException; import java.math.BigInteger; import java.util.Objects; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.core.TreeNode; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; import org.web3j.utils.Base64String; import org.web3j.utils.Numeric; @@ -29,24 +29,25 @@ @JsonDeserialize(using = PrivateTransaction.ResponseDeserialiser.class) public abstract class PrivateTransaction { - public static class ResponseDeserialiser extends StdDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { + + private final ObjectMapper objectMapper = new ObjectMapper(); protected ResponseDeserialiser() { - super(PrivateTransaction.class); + super(); } @Override - public PrivateTransaction deserialize(JsonParser p, DeserializationContext ctxt) - throws IOException { + public PrivateTransaction deserialize(JsonParser p, DeserializationContext ctxt) { final TreeNode node = p.readValueAsTree(); // Select the concrete class based on the existence of a property if (node.get("privateFor") != null && node.get("privateFor").isArray()) { - return p.getCodec().treeToValue(node, PrivateTransactionLegacy.class); + return objectMapper.convertValue(node, PrivateTransactionLegacy.class); } else if ((node.get("privateFor") != null && node.get("privateFor").isValueNode()) || (node.get("privacyGroupId") != null && node.get("privacyGroupId").isValueNode())) { - return p.getCodec().treeToValue(node, PrivateTransactionWithPrivacyGroup.class); + return objectMapper.convertValue(node, PrivateTransactionWithPrivacyGroup.class); } return null; diff --git a/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransactionLegacy.java b/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransactionLegacy.java index 9ebba3580f..0b4d7d4b46 100644 --- a/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransactionLegacy.java +++ b/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransactionLegacy.java @@ -17,12 +17,12 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; import org.web3j.utils.Base64String; -@JsonDeserialize(using = JsonDeserializer.None.class) +@JsonDeserialize(using = ValueDeserializer.None.class) public class PrivateTransactionLegacy extends PrivateTransaction { private List privateFor; diff --git a/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransactionWithPrivacyGroup.java b/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransactionWithPrivacyGroup.java index 98afb50589..7d99817e89 100644 --- a/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransactionWithPrivacyGroup.java +++ b/besu/src/main/java/org/web3j/protocol/besu/response/privacy/PrivateTransactionWithPrivacyGroup.java @@ -16,12 +16,12 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; import org.web3j.utils.Base64String; -@JsonDeserialize(using = JsonDeserializer.None.class) +@JsonDeserialize(using = ValueDeserializer.None.class) public class PrivateTransactionWithPrivacyGroup extends PrivateTransaction { private Base64String privacyGroupId; diff --git a/build.gradle b/build.gradle index 22669f159e..5f7920afc6 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,8 @@ plugins { ext { bouncycastleVersion = '1.80' - jacksonVersion = '2.17.1' + jacksonVersion = '3.1.0' + jacksonAnnotationsVersion = '2.17.1' javaPoetVersion = '1.13.0' kotlinVersion = '1.9.24' kotlinPoetVersion = '1.16.0' @@ -87,9 +88,9 @@ allprojects { force(group: "org.jetbrains.kotlin", name: "kotlin-stdlib-common", version: kotlinVersion) force(group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk7", version: kotlinVersion) force(group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk8", version: kotlinVersion) - force(group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jacksonVersion) - force(group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion) - force(group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jacksonVersion) + force(group: 'tools.jackson.core', name: 'jackson-core', version: jacksonVersion) + force(group: 'tools.jackson.core', name: 'jackson-databind', version: jacksonVersion) + force(group: 'tools.jackson.core', name: 'jackson-annotations', version: jacksonAnnotationsVersion) force(group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion) } } diff --git a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java index babf1e06f3..4d4b44b5c8 100644 --- a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java +++ b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapper.java @@ -30,7 +30,6 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.Modifier; -import com.fasterxml.jackson.databind.ObjectMapper; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; @@ -45,6 +44,7 @@ import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import tools.jackson.databind.ObjectMapper; import org.web3j.abi.EventEncoder; import org.web3j.abi.FunctionEncoder; diff --git a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapperGenerator.java b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapperGenerator.java index 9c76f2d099..8d2d75ef0d 100644 --- a/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapperGenerator.java +++ b/codegen/src/main/java/org/web3j/codegen/SolidityFunctionWrapperGenerator.java @@ -17,10 +17,10 @@ import java.util.Arrays; import java.util.List; -import com.fasterxml.jackson.databind.ObjectMapper; import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Option; +import tools.jackson.databind.ObjectMapper; import org.web3j.abi.datatypes.Address; import org.web3j.protocol.ObjectMapperFactory; diff --git a/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java b/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java index b2f5c945e4..dd2f96805d 100644 --- a/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java +++ b/codegen/src/main/java/org/web3j/codegen/TruffleJsonFunctionWrapperGenerator.java @@ -30,9 +30,9 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import picocli.CommandLine; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import org.web3j.abi.datatypes.Address; import org.web3j.protocol.ObjectMapperFactory; diff --git a/core/build.gradle b/core/build.gradle index 4cc9d22931..868ea2ffd7 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -16,7 +16,7 @@ dependencies { "com.squareup.okhttp3:logging-interceptor:$okhttpVersion", "io.reactivex.rxjava2:rxjava:$rxjavaVersion", "org.java-websocket:Java-WebSocket:$javaWebSocketVersion", - "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion", + "tools.jackson.core:jackson-databind:$jacksonVersion", "org.slf4j:slf4j-api:$slf4jVersion", "io.github.adraffy:ens-normalize:$ensAdraffyVersion", "io.consensys.tuweni:tuweni-bytes:$tuweniVersion", diff --git a/core/src/main/java/org/web3j/crypto/WalletFile.java b/core/src/main/java/org/web3j/crypto/WalletFile.java index bf9deb3f57..557ffe7e32 100644 --- a/core/src/main/java/org/web3j/crypto/WalletFile.java +++ b/core/src/main/java/org/web3j/crypto/WalletFile.java @@ -12,17 +12,15 @@ */ package org.web3j.crypto; -import java.io.IOException; - import com.fasterxml.jackson.annotation.JsonSetter; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.node.ObjectNode; /** Ethereum wallet file. */ public class WalletFile { @@ -429,15 +427,15 @@ public int hashCode() { // If we need to work with MyEtherWallet we'll need to use this deserializer, see the // following issue https://github.com/kvhnuke/etherwallet/issues/269 - static class KdfParamsDeserialiser extends JsonDeserializer { + static class KdfParamsDeserialiser extends ValueDeserializer { + + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public KdfParams deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { + JsonParser jsonParser, DeserializationContext deserializationContext) { - ObjectMapper objectMapper = (ObjectMapper) jsonParser.getCodec(); - ObjectNode root = objectMapper.readTree(jsonParser); + ObjectNode root = jsonParser.readValueAsTree(); KdfParams kdfParams; // it would be preferable to detect the class to use based on the kdf parameter in the diff --git a/core/src/main/java/org/web3j/crypto/WalletUtils.java b/core/src/main/java/org/web3j/crypto/WalletUtils.java index 9e210544bf..623d9b874f 100644 --- a/core/src/main/java/org/web3j/crypto/WalletUtils.java +++ b/core/src/main/java/org/web3j/crypto/WalletUtils.java @@ -22,9 +22,10 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.json.JsonMapper; import org.web3j.crypto.exception.CipherException; import org.web3j.utils.Numeric; @@ -36,14 +37,14 @@ /** Utility functions for working with Wallet files. */ public class WalletUtils { - private static final ObjectMapper objectMapper = new ObjectMapper(); + private static final ObjectMapper objectMapper = + JsonMapper.builder() + .enable(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) + .build(); private static final SecureRandom secureRandom = SecureRandomUtils.secureRandom(); - static { - objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } - public static String generateFullNewWalletFile(String password, File destinationDirectory) throws NoSuchAlgorithmException, NoSuchProviderException, diff --git a/core/src/main/java/org/web3j/ens/EnsMetadataResponse.java b/core/src/main/java/org/web3j/ens/EnsMetadataResponse.java index 0c91390ccf..2e3876003a 100644 --- a/core/src/main/java/org/web3j/ens/EnsMetadataResponse.java +++ b/core/src/main/java/org/web3j/ens/EnsMetadataResponse.java @@ -12,8 +12,8 @@ */ package org.web3j.ens; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; public class EnsMetadataResponse { public boolean is_normalized; @@ -117,7 +117,7 @@ public static class Attribute { public String toString() { try { return new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { return "Error serializing EnsMetadataResponse: " + e.getMessage(); } } diff --git a/core/src/main/java/org/web3j/ens/EnsResolver.java b/core/src/main/java/org/web3j/ens/EnsResolver.java index 07eb10d93f..8d6a89a2b6 100644 --- a/core/src/main/java/org/web3j/ens/EnsResolver.java +++ b/core/src/main/java/org/web3j/ens/EnsResolver.java @@ -20,8 +20,6 @@ import java.util.List; import java.util.stream.Collectors; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; @@ -29,6 +27,8 @@ import okhttp3.ResponseBody; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import org.web3j.abi.DefaultFunctionEncoder; import org.web3j.abi.DefaultFunctionReturnDecoder; @@ -299,7 +299,7 @@ protected String ccipReadFetch(List urls, String sender, String data) { Request request; try { request = buildRequest(url, sender, data); - } catch (JsonProcessingException | EnsResolutionException e) { + } catch (JacksonException | EnsResolutionException e) { log.error(e.getMessage(), e); break; } @@ -343,8 +343,7 @@ protected String ccipReadFetch(List urls, String sender, String data) { return null; } - protected Request buildRequest(String url, String sender, String data) - throws JsonProcessingException { + protected Request buildRequest(String url, String sender, String data) throws JacksonException { if (sender == null || !WalletUtils.isValidAddress(sender)) { throw new EnsResolutionException("Sender address is null or not valid"); } diff --git a/core/src/main/java/org/web3j/protocol/ObjectMapperFactory.java b/core/src/main/java/org/web3j/protocol/ObjectMapperFactory.java index c146564376..a01d9e219a 100644 --- a/core/src/main/java/org/web3j/protocol/ObjectMapperFactory.java +++ b/core/src/main/java/org/web3j/protocol/ObjectMapperFactory.java @@ -12,15 +12,16 @@ */ package org.web3j.protocol; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.BeanDescription; -import com.fasterxml.jackson.databind.DeserializationConfig; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; -import com.fasterxml.jackson.databind.module.SimpleModule; +import tools.jackson.core.json.JsonReadFeature; +import tools.jackson.databind.BeanDescription; +import tools.jackson.databind.DeserializationConfig; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectReader; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.deser.ValueDeserializerModifier; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.module.SimpleModule; import org.web3j.protocol.core.Response; import org.web3j.protocol.deserializer.RawResponseDeserializer; @@ -28,11 +29,7 @@ /** Factory for managing our ObjectMapper instances. */ public class ObjectMapperFactory { - private static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper(); - - static { - configureObjectMapper(DEFAULT_OBJECT_MAPPER, false); - } + private static final ObjectMapper DEFAULT_OBJECT_MAPPER = buildObjectMapper(false); public static ObjectMapper getObjectMapper() { return getObjectMapper(false); @@ -43,38 +40,41 @@ public static ObjectMapper getObjectMapper(boolean shouldIncludeRawResponses) { return DEFAULT_OBJECT_MAPPER; } - return configureObjectMapper(new ObjectMapper(), true); + return buildObjectMapper(true); } public static ObjectReader getObjectReader() { return DEFAULT_OBJECT_MAPPER.reader(); } - private static ObjectMapper configureObjectMapper( - ObjectMapper objectMapper, boolean shouldIncludeRawResponses) { + private static ObjectMapper buildObjectMapper(boolean shouldIncludeRawResponses) { + JsonMapper.Builder builder = + JsonMapper.builder() + .enable(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES); + if (shouldIncludeRawResponses) { SimpleModule module = new SimpleModule(); module.setDeserializerModifier( - new BeanDeserializerModifier() { + new ValueDeserializerModifier() { @Override - public JsonDeserializer modifyDeserializer( + public ValueDeserializer modifyDeserializer( DeserializationConfig config, - BeanDescription beanDesc, - JsonDeserializer deserializer) { + BeanDescription.Supplier beanDesc, + ValueDeserializer deserializer) { if (Response.class.isAssignableFrom(beanDesc.getBeanClass())) { - return new RawResponseDeserializer(deserializer); + return new RawResponseDeserializer( + (ValueDeserializer) deserializer); } return deserializer; } }); - objectMapper.registerModule(module); + builder.addModule(module); } - objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - return objectMapper; + return builder.build(); } } diff --git a/core/src/main/java/org/web3j/protocol/Service.java b/core/src/main/java/org/web3j/protocol/Service.java index d8ed83b6d9..d1fee4691b 100644 --- a/core/src/main/java/org/web3j/protocol/Service.java +++ b/core/src/main/java/org/web3j/protocol/Service.java @@ -19,9 +19,9 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ArrayNode; import io.reactivex.Flowable; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ArrayNode; import org.web3j.protocol.core.BatchRequest; import org.web3j.protocol.core.BatchResponse; diff --git a/core/src/main/java/org/web3j/protocol/core/Request.java b/core/src/main/java/org/web3j/protocol/core/Request.java index 644a3a62da..e0ba2fa723 100644 --- a/core/src/main/java/org/web3j/protocol/core/Request.java +++ b/core/src/main/java/org/web3j/protocol/core/Request.java @@ -17,10 +17,12 @@ import java.util.concurrent.CompletableFuture; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import io.reactivex.Flowable; import org.web3j.protocol.Web3jService; +@JsonPropertyOrder({"jsonrpc", "method", "params", "id"}) public class Request { private String jsonrpc = "2.0"; private String method; diff --git a/core/src/main/java/org/web3j/protocol/core/Response.java b/core/src/main/java/org/web3j/protocol/core/Response.java index d09f6de756..afded4e206 100644 --- a/core/src/main/java/org/web3j/protocol/core/Response.java +++ b/core/src/main/java/org/web3j/protocol/core/Response.java @@ -13,7 +13,7 @@ package org.web3j.protocol.core; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonDeserialize; import org.web3j.protocol.deserializer.KeepAsJsonDeserialzier; diff --git a/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java b/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java index 0514923db5..5c03d8e14a 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java @@ -15,6 +15,7 @@ import java.math.BigInteger; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import org.web3j.utils.Numeric; @@ -28,6 +29,7 @@ * */ @JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({"from", "to", "data"}) public class Transaction { // default as per https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction public static final BigInteger DEFAULT_GAS = BigInteger.valueOf(9000); diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthBlock.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthBlock.java index 82d96440f3..847a11482a 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthBlock.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthBlock.java @@ -12,19 +12,19 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Objects; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectReader; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; @@ -955,14 +955,13 @@ public Transaction get() { } public static class ResultTransactionDeserialiser - extends JsonDeserializer> { + extends ValueDeserializer> { private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); @Override public List deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { + JsonParser jsonParser, DeserializationContext deserializationContext) { List transactionResults = new ArrayList<>(); JsonToken nextToken = jsonParser.nextToken(); @@ -1051,16 +1050,15 @@ public int hashCode() { } } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public Block deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, Block.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue(jsonParser.readValueAsTree(), Block.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthEstimateUserOperationGas.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthEstimateUserOperationGas.java index 14b36b47e5..b8bd613c46 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthEstimateUserOperationGas.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthEstimateUserOperationGas.java @@ -12,16 +12,13 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; /** eth_estimateUserOperationGas. */ @@ -133,18 +130,17 @@ public int hashCode() { } } - public static class ResponseDeserialiser - extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public EthEstimateUserOperationGas.UserOperationGas deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue( - jsonParser, EthEstimateUserOperationGas.UserOperationGas.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue( + jsonParser.readValueAsTree(), + EthEstimateUserOperationGas.UserOperationGas.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthFeeHistory.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthFeeHistory.java index 823b7ecd0c..5fe51a26ec 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthFeeHistory.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthFeeHistory.java @@ -12,18 +12,16 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; import java.math.BigInteger; import java.util.List; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; import org.web3j.utils.Numeric; @@ -155,16 +153,15 @@ public int hashCode() { } } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public FeeHistory deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, FeeHistory.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue(jsonParser.readValueAsTree(), FeeHistory.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetProof.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetProof.java index 9906c98433..9d383d00fd 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetProof.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetProof.java @@ -12,18 +12,16 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; import java.math.BigInteger; import java.util.List; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; import org.web3j.utils.Numeric; @@ -411,19 +409,19 @@ public int hashCode() { } /** Json Deserializer of Proof. */ - public static class ResponseDeserializer extends JsonDeserializer { + public static class ResponseDeserializer extends ValueDeserializer { /** Instantiates a new Response deserializer. */ public ResponseDeserializer() {} - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public EthGetProof.Proof deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, EthGetProof.Proof.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue( + jsonParser.readValueAsTree(), EthGetProof.Proof.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetTransactionReceipt.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetTransactionReceipt.java index d0435e38e8..f5c19df484 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetTransactionReceipt.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetTransactionReceipt.java @@ -12,16 +12,14 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; import java.util.Optional; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; /** eth_getTransactionReceipt. */ @@ -31,16 +29,16 @@ public Optional getTransactionReceipt() { return Optional.ofNullable(getResult()); } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public TransactionReceipt deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, TransactionReceipt.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue( + jsonParser.readValueAsTree(), TransactionReceipt.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetUserOperationByHash.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetUserOperationByHash.java index d623339233..21d318ff90 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetUserOperationByHash.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetUserOperationByHash.java @@ -12,16 +12,13 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; /** eth_getUserOperationByHash. */ @@ -37,16 +34,16 @@ public UserOperationResult getUserOperation() { return getResult(); } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public UserOperationResult deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, UserOperationResult.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue( + jsonParser.readValueAsTree(), UserOperationResult.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetUserOperationReceipt.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetUserOperationReceipt.java index bac08f168f..4c9791bc1b 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetUserOperationReceipt.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthGetUserOperationReceipt.java @@ -12,16 +12,13 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; /** eth_getUserOperationReceipt. */ @@ -37,16 +34,16 @@ public UserOperationReceipt getOperationReceipt() { return getResult(); } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public UserOperationReceipt deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, UserOperationReceipt.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue( + jsonParser.readValueAsTree(), UserOperationReceipt.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthLog.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthLog.java index c80ca90d67..63eed7a235 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthLog.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthLog.java @@ -12,19 +12,17 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; /** @@ -127,29 +125,28 @@ public int hashCode() { } } - public static class LogResultDeserialiser extends JsonDeserializer> { + public static class LogResultDeserialiser extends ValueDeserializer> { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public List deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { + JsonParser jsonParser, DeserializationContext deserializationContext) { List logResults = new ArrayList<>(); JsonToken nextToken = jsonParser.nextToken(); if (nextToken == JsonToken.START_OBJECT) { Iterator logObjectIterator = - objectReader.readValues(jsonParser, LogObject.class); + objectMapper.readerFor(LogObject.class).readValues(jsonParser); while (logObjectIterator.hasNext()) { logResults.add(logObjectIterator.next()); } } else if (nextToken == JsonToken.VALUE_STRING) { - jsonParser.getValueAsString(); + jsonParser.getString(); Iterator transactionHashIterator = - objectReader.readValues(jsonParser, Hash.class); + objectMapper.readerFor(Hash.class).readValues(jsonParser); while (transactionHashIterator.hasNext()) { logResults.add(transactionHashIterator.next()); } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthSyncing.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthSyncing.java index bacbf4bfd6..fae2bed32b 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthSyncing.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthSyncing.java @@ -12,17 +12,14 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import org.web3j.protocol.ObjectMapperFactory; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; + import org.web3j.protocol.core.Response; /** @@ -156,20 +153,19 @@ public int hashCode() { } } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public Result deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { + JsonParser jsonParser, DeserializationContext deserializationContext) { Result result; - if (jsonParser.getCurrentToken() == JsonToken.VALUE_FALSE) { + if (jsonParser.currentToken() == JsonToken.VALUE_FALSE) { result = new Result(); result.setSyncing(jsonParser.getBooleanValue()); } else { - result = objectReader.readValue(jsonParser, Syncing.class); + result = objectMapper.convertValue(jsonParser.readValueAsTree(), Syncing.class); } return result; } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/EthTransaction.java b/core/src/main/java/org/web3j/protocol/core/methods/response/EthTransaction.java index e663a0019b..eee23d622b 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/EthTransaction.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/EthTransaction.java @@ -12,16 +12,14 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; import java.util.Optional; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; /** @@ -44,16 +42,15 @@ public Optional getTransaction() { return Optional.ofNullable(getResult()); } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public Transaction deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, Transaction.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue(jsonParser.readValueAsTree(), Transaction.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/LineaEstimateGas.java b/core/src/main/java/org/web3j/protocol/core/methods/response/LineaEstimateGas.java index a7d50c75d8..203506a319 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/LineaEstimateGas.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/LineaEstimateGas.java @@ -12,17 +12,15 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; import java.math.BigInteger; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; import org.web3j.utils.Numeric; @@ -104,18 +102,17 @@ public boolean equals(Object o) { } } - public static class ResponseDeserialiser - extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public LineaEstimateGas.LineaEstimateGasResponse deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue( - jsonParser, LineaEstimateGas.LineaEstimateGasResponse.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue( + jsonParser.readValueAsTree(), + LineaEstimateGas.LineaEstimateGasResponse.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/LineaGetProof.java b/core/src/main/java/org/web3j/protocol/core/methods/response/LineaGetProof.java index 3d922639ce..dee1f1ee15 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/LineaGetProof.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/LineaGetProof.java @@ -12,7 +12,7 @@ */ package org.web3j.protocol.core.methods.response; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonDeserialize; import org.web3j.protocol.core.Response; diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/LineaGetTransactionExclusionStatusV1.java b/core/src/main/java/org/web3j/protocol/core/methods/response/LineaGetTransactionExclusionStatusV1.java index 9aa16bb405..7af6aaa39f 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/LineaGetTransactionExclusionStatusV1.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/LineaGetTransactionExclusionStatusV1.java @@ -12,16 +12,13 @@ */ package org.web3j.protocol.core.methods.response; -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.core.Response; public class LineaGetTransactionExclusionStatusV1 @@ -170,16 +167,16 @@ public boolean equals(Object o) { } } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public LineaExclusionStatus deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, LineaExclusionStatus.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue( + jsonParser.readValueAsTree(), LineaExclusionStatus.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/admin/AdminNodeInfo.java b/core/src/main/java/org/web3j/protocol/core/methods/response/admin/AdminNodeInfo.java index 7558a1d9f8..8b35de2b7a 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/admin/AdminNodeInfo.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/admin/AdminNodeInfo.java @@ -12,19 +12,17 @@ */ package org.web3j.protocol.core.methods.response.admin; -import java.io.IOException; import java.util.Map; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import org.web3j.protocol.ObjectMapperFactory; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; + import org.web3j.protocol.core.Response; /** admin_nodeInfo. */ @@ -101,16 +99,15 @@ public String getConsensus() { } } - public static class ResponseDeserialiser extends JsonDeserializer { + public static class ResponseDeserialiser extends ValueDeserializer { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public NodeInfo deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, NodeInfo.class); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue(jsonParser.readValueAsTree(), NodeInfo.class); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/admin/AdminPeers.java b/core/src/main/java/org/web3j/protocol/core/methods/response/admin/AdminPeers.java index 904efa6d97..f73c31be25 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/admin/AdminPeers.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/admin/AdminPeers.java @@ -12,19 +12,17 @@ */ package org.web3j.protocol.core.methods.response.admin; -import java.io.IOException; import java.util.List; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -import org.web3j.protocol.ObjectMapperFactory; +import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; + import org.web3j.protocol.core.Response; /** admin_peers. */ @@ -89,16 +87,16 @@ public String getRemoteAddress() { } } - public static class ResponseDeserialiser extends JsonDeserializer> { + public static class ResponseDeserialiser extends ValueDeserializer> { - private ObjectReader objectReader = ObjectMapperFactory.getObjectReader(); + private final ObjectMapper objectMapper = new ObjectMapper(); @Override public List deserialize( - JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException { - if (jsonParser.getCurrentToken() != JsonToken.VALUE_NULL) { - return objectReader.readValue(jsonParser, new TypeReference>() {}); + JsonParser jsonParser, DeserializationContext deserializationContext) { + if (jsonParser.currentToken() != JsonToken.VALUE_NULL) { + return objectMapper.convertValue( + jsonParser.readValueAsTree(), new TypeReference>() {}); } else { return null; // null is wrapped by Optional in above getter } diff --git a/core/src/main/java/org/web3j/protocol/deserializer/KeepAsJsonDeserialzier.java b/core/src/main/java/org/web3j/protocol/deserializer/KeepAsJsonDeserialzier.java index 45885be102..08ac62adbd 100644 --- a/core/src/main/java/org/web3j/protocol/deserializer/KeepAsJsonDeserialzier.java +++ b/core/src/main/java/org/web3j/protocol/deserializer/KeepAsJsonDeserialzier.java @@ -12,19 +12,16 @@ */ package org.web3j.protocol.deserializer; -import java.io.IOException; +import tools.jackson.core.JsonParser; +import tools.jackson.core.TreeNode; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ValueDeserializer; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; - -public class KeepAsJsonDeserialzier extends JsonDeserializer { +public class KeepAsJsonDeserialzier extends ValueDeserializer { @Override - public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { - - TreeNode tree = jp.getCodec().readTree(jp); + public String deserialize(JsonParser jp, DeserializationContext ctxt) { + TreeNode tree = jp.readValueAsTree(); return tree.toString(); } } diff --git a/core/src/main/java/org/web3j/protocol/deserializer/RawResponseDeserializer.java b/core/src/main/java/org/web3j/protocol/deserializer/RawResponseDeserializer.java index a801950532..513989afa2 100644 --- a/core/src/main/java/org/web3j/protocol/deserializer/RawResponseDeserializer.java +++ b/core/src/main/java/org/web3j/protocol/deserializer/RawResponseDeserializer.java @@ -17,56 +17,49 @@ import java.nio.charset.StandardCharsets; import java.util.Scanner; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.deser.ResolvableDeserializer; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.deser.std.StdDeserializer; import org.web3j.protocol.core.Response; /** A jackson deserializer that sets the rawResponse variable of Response objects. */ -public class RawResponseDeserializer extends StdDeserializer - implements ResolvableDeserializer { +@SuppressWarnings("rawtypes") +public class RawResponseDeserializer extends StdDeserializer { - private final JsonDeserializer defaultDeserializer; + private final ValueDeserializer defaultDeserializer; - public RawResponseDeserializer(JsonDeserializer defaultDeserializer) { + public RawResponseDeserializer(ValueDeserializer defaultDeserializer) { super(Response.class); this.defaultDeserializer = defaultDeserializer; } @Override - public Response deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { + public Response deserialize(JsonParser jp, DeserializationContext ctxt) { Response deserializedResponse = (Response) defaultDeserializer.deserialize(jp, ctxt); - deserializedResponse.setRawResponse(getRawResponse(jp)); return deserializedResponse; } - // Must implement ResolvableDeserializer when modifying BeanDeserializer - // otherwise deserializing throws JsonMappingException - @Override - public void resolve(DeserializationContext ctxt) throws JsonMappingException { - ((ResolvableDeserializer) defaultDeserializer).resolve(ctxt); - } + private String getRawResponse(JsonParser jp) { + try { + final InputStream inputSource = + jp.streamReadConstraints() != null ? (InputStream) jp.currentValue() : null; - private String getRawResponse(JsonParser jp) throws IOException { - final InputStream inputSource = (InputStream) jp.getInputSource(); + if (inputSource == null) { + return ""; + } - if (inputSource == null) { + inputSource.reset(); + return streamToString(inputSource); + } catch (IOException e) { return ""; } - - inputSource.reset(); - - return streamToString(inputSource); } private String streamToString(InputStream input) throws IOException { - try (Scanner scanner = - new Scanner(input, StandardCharsets.UTF_8.name()).useDelimiter("\\Z")) { + try (Scanner scanner = new Scanner(input, StandardCharsets.UTF_8).useDelimiter("\\Z")) { return scanner.next(); } } diff --git a/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java b/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java index 2a208fc1f4..6f46a0cd39 100644 --- a/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java +++ b/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java @@ -28,16 +28,16 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; -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.reactivex.BackpressureStrategy; import io.reactivex.Flowable; import io.reactivex.subjects.BehaviorSubject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +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; import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.Web3jService; @@ -193,7 +193,7 @@ public CompletableFuture sendAsync( requestForId.put(requestId, new WebSocketRequest<>(result, responseType)); try { sendRequest(request, requestId); - } catch (IOException e) { + } catch (JacksonException e) { closeRequest(requestId, e); } @@ -231,22 +231,21 @@ public CompletableFuture sendBatchAsync(BatchRequest requests) { try { sendBatchRequest(requests, requestId); - } catch (IOException e) { + } catch (JacksonException e) { closeRequest(requestId, e); } return result; } - private void sendRequest(Request request, long requestId) throws JsonProcessingException { + private void sendRequest(Request request, long requestId) throws JacksonException { String payload = objectMapper.writeValueAsString(request); log.debug("Sending request: {}", payload); webSocketClient.send(payload); setRequestTimeout(requestId); } - private void sendBatchRequest(BatchRequest request, long requestId) - throws JsonProcessingException { + private void sendBatchRequest(BatchRequest request, long requestId) throws JacksonException { String payload = objectMapper.writeValueAsString(request.getRequests()); log.debug("Sending batch request: {}", payload); webSocketClient.send(payload); @@ -419,7 +418,7 @@ private boolean isSubscriptionEvent(JsonNode replyJson) { private JsonNode parseToTree(String replyStr) throws IOException { try { return objectMapper.readTree(replyStr); - } catch (IOException e) { + } catch (JacksonException e) { throw new IOException("Failed to parse incoming WebSocket message", e); } } diff --git a/core/src/test/java/org/web3j/crypto/WalletFileTest.java b/core/src/test/java/org/web3j/crypto/WalletFileTest.java index 51b996d6ac..6d0ea4553e 100644 --- a/core/src/test/java/org/web3j/crypto/WalletFileTest.java +++ b/core/src/test/java/org/web3j/crypto/WalletFileTest.java @@ -14,8 +14,8 @@ import java.io.IOException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/core/src/test/java/org/web3j/crypto/WalletTest.java b/core/src/test/java/org/web3j/crypto/WalletTest.java index 584f1404af..ad652ba730 100644 --- a/core/src/test/java/org/web3j/crypto/WalletTest.java +++ b/core/src/test/java/org/web3j/crypto/WalletTest.java @@ -14,8 +14,8 @@ import java.io.IOException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; import org.web3j.utils.Numeric; diff --git a/core/src/test/java/org/web3j/ens/EnsResolverTest.java b/core/src/test/java/org/web3j/ens/EnsResolverTest.java index 80ec48bf35..3d3119c294 100644 --- a/core/src/test/java/org/web3j/ens/EnsResolverTest.java +++ b/core/src/test/java/org/web3j/ens/EnsResolverTest.java @@ -17,8 +17,6 @@ import java.util.ArrayList; import java.util.List; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.Call; import okhttp3.MediaType; import okhttp3.OkHttpClient; @@ -29,6 +27,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import org.web3j.abi.TypeEncoder; import org.web3j.abi.datatypes.Utf8String; @@ -792,7 +792,7 @@ void testGetEnsMetadataSuccess() throws Exception { } private okhttp3.Response buildResponse(int code, String url, String sender, String data) - throws JsonProcessingException { + throws JacksonException { EnsGatewayResponseDTO responseDTO = new EnsGatewayResponseDTO(data); return new okhttp3.Response.Builder() diff --git a/core/src/test/java/org/web3j/protocol/BatchTester.java b/core/src/test/java/org/web3j/protocol/BatchTester.java index 64b7f38fb1..8f5bef97ff 100644 --- a/core/src/test/java/org/web3j/protocol/BatchTester.java +++ b/core/src/test/java/org/web3j/protocol/BatchTester.java @@ -14,7 +14,6 @@ import java.io.IOException; -import com.fasterxml.jackson.databind.node.ArrayNode; import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.OkHttpClient; @@ -24,6 +23,7 @@ import okhttp3.ResponseBody; import okio.Buffer; import org.junit.jupiter.api.BeforeEach; +import tools.jackson.databind.node.ArrayNode; import org.web3j.protocol.http.HttpService; diff --git a/core/src/test/java/org/web3j/protocol/core/WebSocketEventTest.java b/core/src/test/java/org/web3j/protocol/core/WebSocketEventTest.java index 10bbe414c2..b32b9242e2 100644 --- a/core/src/test/java/org/web3j/protocol/core/WebSocketEventTest.java +++ b/core/src/test/java/org/web3j/protocol/core/WebSocketEventTest.java @@ -16,10 +16,10 @@ import java.util.ArrayList; import java.util.Collections; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.Web3j; diff --git a/core/src/test/java/org/web3j/protocol/core/filters/FilterTester.java b/core/src/test/java/org/web3j/protocol/core/filters/FilterTester.java index c36138589e..bebe0201e8 100644 --- a/core/src/test/java/org/web3j/protocol/core/filters/FilterTester.java +++ b/core/src/test/java/org/web3j/protocol/core/filters/FilterTester.java @@ -21,10 +21,10 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import com.fasterxml.jackson.databind.ObjectMapper; import io.reactivex.Flowable; import io.reactivex.disposables.Disposable; import org.junit.jupiter.api.BeforeEach; +import tools.jackson.databind.ObjectMapper; import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.Web3j; diff --git a/core/src/test/java/org/web3j/protocol/rx/JsonRpc2_0RxTest.java b/core/src/test/java/org/web3j/protocol/rx/JsonRpc2_0RxTest.java index 27d617f452..27ce2cba0b 100644 --- a/core/src/test/java/org/web3j/protocol/rx/JsonRpc2_0RxTest.java +++ b/core/src/test/java/org/web3j/protocol/rx/JsonRpc2_0RxTest.java @@ -22,12 +22,12 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import com.fasterxml.jackson.databind.ObjectMapper; import io.reactivex.Flowable; import io.reactivex.disposables.Disposable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.stubbing.OngoingStubbing; +import tools.jackson.databind.ObjectMapper; import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.Web3j; diff --git a/core/src/test/java/org/web3j/tx/HSMHTTPRequestProcessorTestImpl.java b/core/src/test/java/org/web3j/tx/HSMHTTPRequestProcessorTestImpl.java index 58fc81ea70..6b747813a9 100644 --- a/core/src/test/java/org/web3j/tx/HSMHTTPRequestProcessorTestImpl.java +++ b/core/src/test/java/org/web3j/tx/HSMHTTPRequestProcessorTestImpl.java @@ -17,14 +17,14 @@ import java.io.InputStreamReader; import java.util.stream.Collectors; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectWriter; import org.web3j.crypto.HSMHTTPPass; import org.web3j.dto.HSMHTTPRequestDTO; @@ -48,7 +48,7 @@ protected Request createRequest(byte[] dataToSign, HSMHTTPPass pass) { String json; try { json = ow.writeValueAsString(requestDto); - } catch (JsonProcessingException e) { + } catch (JacksonException e) { log.error(e.getMessage(), e); throw new RuntimeException(e); } diff --git a/core/src/test/java/org/web3j/tx/RawTransactionManagerTest.java b/core/src/test/java/org/web3j/tx/RawTransactionManagerTest.java index 7465b04712..ad7c83ad50 100644 --- a/core/src/test/java/org/web3j/tx/RawTransactionManagerTest.java +++ b/core/src/test/java/org/web3j/tx/RawTransactionManagerTest.java @@ -91,7 +91,7 @@ void testSignRawTxWithHSM() throws IOException { TxSignService txHSMSignService = new TxHSMSignService<>(hsmRequestProcessor, hsmhttpPass); RawTransactionManager transactionManager = - new RawTransactionManager(web3j, txHSMSignService, ChainId.NONE); + new RawTransactionManager(web3j, txHSMSignService, ChainIdLong.NONE); String sign = transactionManager.sign(createRawTx()); diff --git a/crypto/build.gradle b/crypto/build.gradle index 4a0a83414b..2bce89f29b 100644 --- a/crypto/build.gradle +++ b/crypto/build.gradle @@ -9,7 +9,7 @@ dependencies { project(':rlp'), project(':utils'), "org.slf4j:slf4j-api:$slf4jVersion", - "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion", + "tools.jackson.core:jackson-databind:$jacksonVersion", "io.consensys.protocols:jc-kzg-4844:$kzg4844Version" implementation("io.consensys.tuweni:tuweni-bytes:$tuweniVersion") implementation("io.consensys.tuweni:tuweni-units:$tuweniVersion") diff --git a/crypto/src/main/java/org/web3j/crypto/Secp256k1JWK.java b/crypto/src/main/java/org/web3j/crypto/Secp256k1JWK.java index da6cd6f718..724a44ef96 100644 --- a/crypto/src/main/java/org/web3j/crypto/Secp256k1JWK.java +++ b/crypto/src/main/java/org/web3j/crypto/Secp256k1JWK.java @@ -15,10 +15,10 @@ import java.math.BigInteger; import java.util.Base64; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonPOJOBuilder; /** * This class consists in java representation of JWK file. It uses Builder pattern in order to diff --git a/crypto/src/main/java/org/web3j/crypto/StructuredDataEncoder.java b/crypto/src/main/java/org/web3j/crypto/StructuredDataEncoder.java index 143fcfdb1b..e90ba7cfd7 100644 --- a/crypto/src/main/java/org/web3j/crypto/StructuredDataEncoder.java +++ b/crypto/src/main/java/org/web3j/crypto/StructuredDataEncoder.java @@ -30,8 +30,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.ObjectMapper; +import tools.jackson.databind.ObjectMapper; import org.web3j.abi.TypeEncoder; import org.web3j.abi.datatypes.AbiTypes; @@ -43,8 +42,7 @@ import static org.web3j.crypto.Hash.sha3String; public class StructuredDataEncoder { - public static ObjectMapper mapper = - new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); + public static ObjectMapper mapper = new ObjectMapper(); public final StructuredData.EIP712Message jsonMessageObject; // Matches array declarations like arr[5][10], arr[][], arr[][34][], etc. diff --git a/crypto/src/test/java/org/web3j/crypto/Secp256k1JWKTest.java b/crypto/src/test/java/org/web3j/crypto/Secp256k1JWKTest.java index 03723fbb87..1185bdd6b9 100644 --- a/crypto/src/test/java/org/web3j/crypto/Secp256k1JWKTest.java +++ b/crypto/src/test/java/org/web3j/crypto/Secp256k1JWKTest.java @@ -24,7 +24,6 @@ import java.security.spec.ECPoint; import java.util.Base64; -import com.fasterxml.jackson.databind.ObjectMapper; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; @@ -35,6 +34,7 @@ import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve; import org.bouncycastle.math.ec.custom.sec.SecP256K1Point; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/crypto/src/test/java/org/web3j/crypto/StructuredDataTest.java b/crypto/src/test/java/org/web3j/crypto/StructuredDataTest.java index 970f933a78..527839ed7d 100644 --- a/crypto/src/test/java/org/web3j/crypto/StructuredDataTest.java +++ b/crypto/src/test/java/org/web3j/crypto/StructuredDataTest.java @@ -23,9 +23,9 @@ import java.util.List; import java.util.Set; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.databind.ObjectMapper; import org.web3j.utils.Numeric; diff --git a/eea/src/main/java/org/web3j/utils/Base64String.java b/eea/src/main/java/org/web3j/utils/Base64String.java index a262e13025..986836f0e7 100644 --- a/eea/src/main/java/org/web3j/utils/Base64String.java +++ b/eea/src/main/java/org/web3j/utils/Base64String.java @@ -12,20 +12,19 @@ */ package org.web3j.utils; -import java.io.IOException; import java.util.Arrays; import java.util.Base64; import java.util.List; import java.util.stream.Collectors; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import tools.jackson.core.JsonGenerator; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.SerializationContext; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.ValueSerializer; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.annotation.JsonSerialize; import org.web3j.rlp.RlpList; import org.web3j.rlp.RlpString; @@ -34,20 +33,20 @@ @JsonDeserialize(using = Base64String.Deserializer.class) public class Base64String { - public static class Serializer extends JsonSerializer { + public static class Serializer extends ValueSerializer { @Override public void serialize( - final Object value, JsonGenerator gen, final SerializerProvider serializers) - throws IOException { + final Base64String value, + final JsonGenerator gen, + final SerializationContext serializers) { gen.writeString(value.toString()); } } - public static class Deserializer extends JsonDeserializer { + public static class Deserializer extends ValueDeserializer { @Override - public Object deserialize(final JsonParser p, final DeserializationContext ctxt) - throws IOException { - return Base64String.wrap(p.getText()); + public Base64String deserialize(final JsonParser p, final DeserializationContext ctxt) { + return Base64String.wrap(p.getValueAsString()); } } diff --git a/geth/src/test/java/org/web3j/protocol/geth/JsonRpc2_0GethTest.java b/geth/src/test/java/org/web3j/protocol/geth/JsonRpc2_0GethTest.java index 8e27dfcec2..b72946f31a 100644 --- a/geth/src/test/java/org/web3j/protocol/geth/JsonRpc2_0GethTest.java +++ b/geth/src/test/java/org/web3j/protocol/geth/JsonRpc2_0GethTest.java @@ -14,10 +14,10 @@ import java.io.IOException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; import org.web3j.protocol.ObjectMapperFactory; import org.web3j.protocol.websocket.WebSocketClient; diff --git a/parity/src/main/java/org/web3j/protocol/parity/methods/response/StateDiff.java b/parity/src/main/java/org/web3j/protocol/parity/methods/response/StateDiff.java index 268ac68b05..2a2eaa8dae 100644 --- a/parity/src/main/java/org/web3j/protocol/parity/methods/response/StateDiff.java +++ b/parity/src/main/java/org/web3j/protocol/parity/methods/response/StateDiff.java @@ -15,7 +15,7 @@ import java.util.Map; import java.util.stream.Collectors; -import com.fasterxml.jackson.databind.JsonNode; +import tools.jackson.databind.JsonNode; /** * StateDiff used in following methods. diff --git a/parity/src/main/java/org/web3j/protocol/parity/methods/response/Trace.java b/parity/src/main/java/org/web3j/protocol/parity/methods/response/Trace.java index d226ac8bf2..b33d75d951 100644 --- a/parity/src/main/java/org/web3j/protocol/parity/methods/response/Trace.java +++ b/parity/src/main/java/org/web3j/protocol/parity/methods/response/Trace.java @@ -16,12 +16,12 @@ import java.math.BigInteger; import java.util.List; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.node.ObjectNode; +import tools.jackson.core.JsonParser; +import tools.jackson.databind.DeserializationContext; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.ValueDeserializer; +import tools.jackson.databind.annotation.JsonDeserialize; +import tools.jackson.databind.node.ObjectNode; import org.web3j.utils.Numeric; @@ -825,13 +825,13 @@ public String toString() { + '}'; } - public static class ActionDeserializer extends JsonDeserializer { + public static class ActionDeserializer extends ValueDeserializer { + + private final ObjectMapper objectMapper = new ObjectMapper(); @Override - public Action deserialize(JsonParser jsonParser, DeserializationContext context) - throws IOException { - ObjectMapper objectMapper = (ObjectMapper) jsonParser.getCodec(); - ObjectNode root = objectMapper.readTree(jsonParser); + public Action deserialize(JsonParser jsonParser, DeserializationContext context) { + ObjectNode root = jsonParser.readValueAsTree(); if (root.has("callType")) { return objectMapper.convertValue(root, CallAction.class); From 1167fd64e92a7c03128edc8351fa16186cc80fe3 Mon Sep 17 00:00:00 2001 From: Julius Lauterbach Date: Tue, 28 Apr 2026 16:34:15 +0200 Subject: [PATCH 2/8] Updates for RequestTest Signed-off-by: Julius Lauterbach --- .../core/methods/request/EthFilter.java | 2 + .../core/methods/request/ShhFilter.java | 2 + .../core/methods/request/ShhPost.java | 2 + .../core/methods/request/Transaction.java | 2 +- .../org/web3j/protocol/core/RequestTest.java | 42 ++++++++++++++++--- 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/web3j/protocol/core/methods/request/EthFilter.java b/core/src/main/java/org/web3j/protocol/core/methods/request/EthFilter.java index a48c1de734..c76d48d9da 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/request/EthFilter.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/request/EthFilter.java @@ -17,12 +17,14 @@ import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import org.web3j.protocol.core.DefaultBlockParameter; /** * Filter implementation as per docs. */ +@JsonPropertyOrder({"address", "blockHash", "fromBlock", "toBlock", "topics"}) public class EthFilter extends Filter { private DefaultBlockParameter fromBlock; // optional, params - defaults to latest for both private DefaultBlockParameter toBlock; diff --git a/core/src/main/java/org/web3j/protocol/core/methods/request/ShhFilter.java b/core/src/main/java/org/web3j/protocol/core/methods/request/ShhFilter.java index be0c27f02a..f2ce60e069 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/request/ShhFilter.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/request/ShhFilter.java @@ -13,11 +13,13 @@ package org.web3j.protocol.core.methods.request; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; /** * Filter implementation as per docs */ +@JsonPropertyOrder({"topics", "to", "data"}) public class ShhFilter extends Filter { private String to; diff --git a/core/src/main/java/org/web3j/protocol/core/methods/request/ShhPost.java b/core/src/main/java/org/web3j/protocol/core/methods/request/ShhPost.java index 2c5810fc9f..b861a615ca 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/request/ShhPost.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/request/ShhPost.java @@ -17,10 +17,12 @@ import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import org.web3j.utils.Numeric; /** https://github.com/ethereum/wiki/wiki/JSON-RPC#shh_post */ @JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({"from", "to", "topics", "payload", "priority", "ttl"}) public class ShhPost { private String from; private String to; diff --git a/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java b/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java index 5c03d8e14a..c36dbcbd98 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java @@ -29,7 +29,7 @@ * */ @JsonInclude(JsonInclude.Include.NON_NULL) -@JsonPropertyOrder({"from", "to", "data"}) +@JsonPropertyOrder({"from", "to", "gas", "gasPrice", "value", "data", "nonce", "chainId", "maxPriorityFeePerGas", "maxFeePerGas"}) public class Transaction { // default as per https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sendtransaction public static final BigInteger DEFAULT_GAS = BigInteger.valueOf(9000); diff --git a/core/src/test/java/org/web3j/protocol/core/RequestTest.java b/core/src/test/java/org/web3j/protocol/core/RequestTest.java index a8ab862523..5bdcec8470 100644 --- a/core/src/test/java/org/web3j/protocol/core/RequestTest.java +++ b/core/src/test/java/org/web3j/protocol/core/RequestTest.java @@ -381,7 +381,19 @@ void testEthSendUserOperation() throws Exception { verifyResult( "{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendUserOperation\"," - + "\"params\":[{\"sender\":\"0xa70e8dd61c5d32be8058bb8eb970870f07233155\",\"nonce\":\"0x1\",\"initCode\":\"0x0\",\"callData\":\"0x0\",\"callGasLimit\":\"0x0\",\"verificationGasLimit\":\"0x0\",\"preVerificationGas\":\"0x0\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\",\"signature\":\"0x0\",\"paymasterAndData\":\"0x0\"},\"0xa70e8dd61c5d32be8058bb8eb970870f07233156\"]," + + "\"params\":[{" + + "\"callData\":\"0x0\"," + + "\"callGasLimit\":\"0x0\"," + + "\"initCode\":\"0x0\"," + + "\"maxFeePerGas\":\"0x0\"," + + "\"maxPriorityFeePerGas\":\"0x0\"," + + "\"nonce\":\"0x1\"," + + "\"paymasterAndData\":\"0x0\"," + + "\"preVerificationGas\":\"0x0\"," + + "\"sender\":\"0xa70e8dd61c5d32be8058bb8eb970870f07233155\"," + + "\"signature\":\"0x0\"," + + "\"verificationGasLimit\":\"0x0\"" + + "},\"0xa70e8dd61c5d32be8058bb8eb970870f07233156\"]," + "\"id\":1}"); } @@ -405,7 +417,19 @@ void testEthEstimateUserOperationGas() throws Exception { verifyResult( "{\"jsonrpc\":\"2.0\",\"method\":\"eth_estimateUserOperationGas\"," - + "\"params\":[{\"sender\":\"0xa70e8dd61c5d32be8058bb8eb970870f07233155\",\"nonce\":\"0x1\",\"initCode\":\"0x0\",\"callData\":\"0x0\",\"callGasLimit\":\"0x0\",\"verificationGasLimit\":\"0x0\",\"preVerificationGas\":\"0x0\",\"maxFeePerGas\":\"0x0\",\"maxPriorityFeePerGas\":\"0x0\",\"signature\":\"0x0\",\"paymasterAndData\":\"0x0\"},\"0xa70e8dd61c5d32be8058bb8eb970870f07233156\"]," + + "\"params\":[{" + + "\"callData\":\"0x0\"," + + "\"callGasLimit\":\"0x0\"," + + "\"initCode\":\"0x0\"," + + "\"maxFeePerGas\":\"0x0\"," + + "\"maxPriorityFeePerGas\":\"0x0\"," + + "\"nonce\":\"0x1\"," + + "\"paymasterAndData\":\"0x0\"," + + "\"preVerificationGas\":\"0x0\"," + + "\"sender\":\"0xa70e8dd61c5d32be8058bb8eb970870f07233155\"," + + "\"signature\":\"0x0\"," + + "\"verificationGasLimit\":\"0x0\"}," + + "\"0xa70e8dd61c5d32be8058bb8eb970870f07233156\"]," + "\"id\":1}"); } @@ -678,8 +702,12 @@ void testEthGetLogsWithNumericBlockRange() throws Exception { verifyResult( "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getLogs\"," - + "\"params\":[{\"topics\":[],\"fromBlock\":\"0xe8\"," - + "\"toBlock\":\"latest\",\"address\":[\"\"]}],\"id\":1}"); + + "\"params\":[{" + + "\"address\":[\"\"]," + + "\"fromBlock\":\"0xe8\"," + + "\"toBlock\":\"latest\"," + + "\"topics\":[]" + + "}],\"id\":1}"); } @Test @@ -692,9 +720,11 @@ void testEthGetLogsWithBlockHash() throws Exception { verifyResult( "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getLogs\"," - + "\"params\":[{\"topics\":[]," + + "\"params\":[{" + + "\"address\":[\"\"]," + "\"blockHash\":\"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331\"," - + "\"address\":[\"\"]}],\"id\":}"); + + "\"topics\":[]" + + "}],\"id\":}"); } @Test From 238ee937ff016741f5beaaeba0826cb90b9dc5a2 Mon Sep 17 00:00:00 2001 From: Julius Lauterbach Date: Tue, 28 Apr 2026 16:57:15 +0200 Subject: [PATCH 3/8] updates for WebSocketServiceTest & ResponseTest Signed-off-by: Julius Lauterbach --- .../web3j/protocol/ObjectMapperFactory.java | 43 ++----------------- .../main/java/org/web3j/protocol/Service.java | 20 ++++++++- .../deserializer/KeepAsJsonDeserialzier.java | 7 ++- .../protocol/websocket/WebSocketService.java | 20 ++++++--- 4 files changed, 41 insertions(+), 49 deletions(-) diff --git a/core/src/main/java/org/web3j/protocol/ObjectMapperFactory.java b/core/src/main/java/org/web3j/protocol/ObjectMapperFactory.java index a01d9e219a..982286d519 100644 --- a/core/src/main/java/org/web3j/protocol/ObjectMapperFactory.java +++ b/core/src/main/java/org/web3j/protocol/ObjectMapperFactory.java @@ -13,68 +13,31 @@ package org.web3j.protocol; import tools.jackson.core.json.JsonReadFeature; -import tools.jackson.databind.BeanDescription; -import tools.jackson.databind.DeserializationConfig; import tools.jackson.databind.DeserializationFeature; import tools.jackson.databind.ObjectMapper; import tools.jackson.databind.ObjectReader; -import tools.jackson.databind.ValueDeserializer; -import tools.jackson.databind.deser.ValueDeserializerModifier; import tools.jackson.databind.json.JsonMapper; -import tools.jackson.databind.module.SimpleModule; - -import org.web3j.protocol.core.Response; -import org.web3j.protocol.deserializer.RawResponseDeserializer; /** Factory for managing our ObjectMapper instances. */ public class ObjectMapperFactory { - private static final ObjectMapper DEFAULT_OBJECT_MAPPER = buildObjectMapper(false); + private static final ObjectMapper DEFAULT_OBJECT_MAPPER = buildObjectMapper(); public static ObjectMapper getObjectMapper() { - return getObjectMapper(false); - } - - public static ObjectMapper getObjectMapper(boolean shouldIncludeRawResponses) { - if (!shouldIncludeRawResponses) { - return DEFAULT_OBJECT_MAPPER; - } - - return buildObjectMapper(true); + return buildObjectMapper(); } public static ObjectReader getObjectReader() { return DEFAULT_OBJECT_MAPPER.reader(); } - private static ObjectMapper buildObjectMapper(boolean shouldIncludeRawResponses) { + private static ObjectMapper buildObjectMapper() { JsonMapper.Builder builder = JsonMapper.builder() .enable(JsonReadFeature.ALLOW_UNQUOTED_PROPERTY_NAMES) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES); - if (shouldIncludeRawResponses) { - SimpleModule module = new SimpleModule(); - module.setDeserializerModifier( - new ValueDeserializerModifier() { - @Override - public ValueDeserializer modifyDeserializer( - DeserializationConfig config, - BeanDescription.Supplier beanDesc, - ValueDeserializer deserializer) { - if (Response.class.isAssignableFrom(beanDesc.getBeanClass())) { - return new RawResponseDeserializer( - (ValueDeserializer) deserializer); - } - - return deserializer; - } - }); - - builder.addModule(module); - } - return builder.build(); } } diff --git a/core/src/main/java/org/web3j/protocol/Service.java b/core/src/main/java/org/web3j/protocol/Service.java index d1fee4691b..571f9af027 100644 --- a/core/src/main/java/org/web3j/protocol/Service.java +++ b/core/src/main/java/org/web3j/protocol/Service.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -34,8 +35,10 @@ public abstract class Service implements Web3jService { protected final ObjectMapper objectMapper; + private final boolean includeRawResponses; public Service(boolean includeRawResponses) { + this.includeRawResponses = includeRawResponses; objectMapper = ObjectMapperFactory.getObjectMapper(includeRawResponses); } @@ -47,7 +50,12 @@ public T send(Request request, Class responseType) throw try (InputStream result = performIO(payload)) { if (result != null) { - return objectMapper.readValue(result, responseType); + byte[] responseBytes = result.readAllBytes(); + T response = objectMapper.readValue(responseBytes, responseType); + if (includeRawResponses && response != null) { + response.setRawResponse(new String(responseBytes, StandardCharsets.UTF_8)); + } + return response; } else { return null; } @@ -70,13 +78,21 @@ public BatchResponse sendBatch(BatchRequest batchRequest) throws IOException { try (InputStream result = performIO(payload)) { if (result != null) { - ArrayNode nodes = (ArrayNode) objectMapper.readTree(result); + byte[] responseBytes = result.readAllBytes(); + String rawResponse = + includeRawResponses + ? new String(responseBytes, StandardCharsets.UTF_8) + : null; + ArrayNode nodes = (ArrayNode) objectMapper.readTree(responseBytes); List> responses = new ArrayList<>(nodes.size()); for (int i = 0; i < nodes.size(); i++) { Request> request = batchRequest.getRequests().get(i); Response response = objectMapper.treeToValue(nodes.get(i), request.getResponseType()); + if (rawResponse != null) { + response.setRawResponse(rawResponse); + } responses.add(response); } diff --git a/core/src/main/java/org/web3j/protocol/deserializer/KeepAsJsonDeserialzier.java b/core/src/main/java/org/web3j/protocol/deserializer/KeepAsJsonDeserialzier.java index 08ac62adbd..6048941e54 100644 --- a/core/src/main/java/org/web3j/protocol/deserializer/KeepAsJsonDeserialzier.java +++ b/core/src/main/java/org/web3j/protocol/deserializer/KeepAsJsonDeserialzier.java @@ -13,6 +13,7 @@ package org.web3j.protocol.deserializer; import tools.jackson.core.JsonParser; +import tools.jackson.core.JsonToken; import tools.jackson.core.TreeNode; import tools.jackson.databind.DeserializationContext; import tools.jackson.databind.ValueDeserializer; @@ -21,7 +22,11 @@ public class KeepAsJsonDeserialzier extends ValueDeserializer { @Override public String deserialize(JsonParser jp, DeserializationContext ctxt) { + if (jp.currentToken() == JsonToken.VALUE_NULL) { + return null; + } + TreeNode tree = jp.readValueAsTree(); - return tree.toString(); + return tree != null ? tree.toString() : null; } } diff --git a/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java b/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java index 6f46a0cd39..19895788e1 100644 --- a/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java +++ b/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java @@ -73,6 +73,7 @@ public class WebSocketService implements Web3jService { private final ScheduledExecutorService executor; // Object mapper to map incoming JSON objects private final ObjectMapper objectMapper; + private final boolean includeRawResponses; // Map of a sent request id to objects necessary to process this request private Map> requestForId = new ConcurrentHashMap<>(); @@ -98,6 +99,7 @@ public WebSocketService(WebSocketClient webSocketClient, boolean includeRawRespo boolean includeRawResponses) { this.webSocketClient = webSocketClient; this.executor = executor; + this.includeRawResponses = includeRawResponses; this.objectMapper = ObjectMapperFactory.getObjectMapper(includeRawResponses); } @@ -288,7 +290,10 @@ private void processRequestReply(String replyStr, JsonNode replyJson) throws IOE long replyId = getReplyId(replyJson); WebSocketRequest request = getAndRemoveRequest(replyId); try { - Object reply = objectMapper.convertValue(replyJson, request.getResponseType()); + Object reply = objectMapper.treeToValue(replyJson, request.getResponseType()); + if (includeRawResponses && reply instanceof Response) { + ((Response) reply).setRawResponse(replyStr); + } // Instead of sending a reply to a caller asynchronously we need to process it here // to avoid race conditions we need to modify state of this class. if (reply instanceof EthSubscribe) { @@ -315,6 +320,9 @@ private void processBatchRequestReply(String replyStr, ArrayNode replyJson) thro Response response = objectMapper.treeToValue( replyJson.get(i), requests.get(i).getResponseType()); + if (includeRawResponses) { + response.setRawResponse(replyJson.get(i).toString()); + } responses.add(response); } @@ -394,7 +402,7 @@ private void processSubscriptionEvent(String replyStr, JsonNode replyJson) { } private String extractSubscriptionId(JsonNode replyJson) { - return replyJson.get("params").get("subscription").asText(); + return replyJson.get("params").get("subscription").asString(); } @SuppressWarnings("unchecked") @@ -440,19 +448,19 @@ private long getReplyId(JsonNode replyJson) throws IOException { } if (!idField.isIntegralNumber()) { - if (idField.isTextual()) { + if (idField.isString()) { try { - return Long.parseLong(idField.asText()); + return Long.parseLong(idField.asString()); } catch (NumberFormatException e) { throw new IOException( String.format( "Found Textual 'id' that cannot be casted to long. Input : '%s'", - idField.asText())); + idField.asString())); } } else { throw new IOException( String.format( - "'id' expected to be long, but it is: '%s'", idField.asText())); + "'id' expected to be long, but it is: '%s'", idField.asString())); } } From f12e216bdf6b66dd8f8105b7271cbeb99a62aedd Mon Sep 17 00:00:00 2001 From: Julius Lauterbach Date: Tue, 28 Apr 2026 16:58:23 +0200 Subject: [PATCH 4/8] updates for WebSocketServiceTest & ResponseTest Signed-off-by: Julius Lauterbach --- core/src/main/java/org/web3j/protocol/Service.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/web3j/protocol/Service.java b/core/src/main/java/org/web3j/protocol/Service.java index 571f9af027..d32b5590cb 100644 --- a/core/src/main/java/org/web3j/protocol/Service.java +++ b/core/src/main/java/org/web3j/protocol/Service.java @@ -39,7 +39,7 @@ public abstract class Service implements Web3jService { public Service(boolean includeRawResponses) { this.includeRawResponses = includeRawResponses; - objectMapper = ObjectMapperFactory.getObjectMapper(includeRawResponses); + objectMapper = ObjectMapperFactory.getObjectMapper(); } protected abstract InputStream performIO(String payload) throws IOException; From 0e9a04bdf710f66a81cb8a5bfeec2544571ddd57 Mon Sep 17 00:00:00 2001 From: Julius Lauterbach Date: Tue, 28 Apr 2026 17:00:39 +0200 Subject: [PATCH 5/8] refactor: simplify ObjectMapper initialization in WebSocketService Signed-off-by: Julius Lauterbach --- .../java/org/web3j/protocol/websocket/WebSocketService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java b/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java index 19895788e1..29149623f1 100644 --- a/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java +++ b/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java @@ -100,7 +100,7 @@ public WebSocketService(WebSocketClient webSocketClient, boolean includeRawRespo this.webSocketClient = webSocketClient; this.executor = executor; this.includeRawResponses = includeRawResponses; - this.objectMapper = ObjectMapperFactory.getObjectMapper(includeRawResponses); + this.objectMapper = ObjectMapperFactory.getObjectMapper(); } /** From 5b580524dc62b21627306bb2792c1069b85248ee Mon Sep 17 00:00:00 2001 From: Julius Lauterbach Date: Tue, 28 Apr 2026 17:37:43 +0200 Subject: [PATCH 6/8] fixes for ResponseTest Signed-off-by: Julius Lauterbach --- .../core/methods/response/AccessListObject.java | 3 +++ .../core/methods/response/Transaction.java | 14 +++++++++----- .../java/org/web3j/protocol/core/ResponseTest.java | 4 +++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/AccessListObject.java b/core/src/main/java/org/web3j/protocol/core/methods/response/AccessListObject.java index 327ce053b6..0d65828d6f 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/AccessListObject.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/AccessListObject.java @@ -12,9 +12,12 @@ */ package org.web3j.protocol.core.methods.response; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + import java.util.List; import java.util.Objects; +@JsonPropertyOrder({"address", "storageKeys"}) public class AccessListObject { private String address; private List storageKeys; diff --git a/core/src/main/java/org/web3j/protocol/core/methods/response/Transaction.java b/core/src/main/java/org/web3j/protocol/core/methods/response/Transaction.java index 563da12faa..3dd9d75bcf 100644 --- a/core/src/main/java/org/web3j/protocol/core/methods/response/Transaction.java +++ b/core/src/main/java/org/web3j/protocol/core/methods/response/Transaction.java @@ -15,10 +15,14 @@ import java.math.BigInteger; import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; import org.web3j.crypto.TransactionUtils; import org.web3j.utils.Numeric; /** Transaction object used by both {@link EthTransaction} and {@link EthBlock}. */ +@JsonPropertyOrder({"hash", "nonce", "blockHash", "blockNumber", "chainId", "transactionIndex", "from", "to", "value", "gas", "gasPrice", + "input", "creates", "publicKey", "raw", "r", "s", "v", "yParity", "accessList", "type", "maxFeePerGas", + "maxPriorityFeePerGas", "maxFeePerBlobGas", "blobVersionedHashes", "authorizationList"}) public class Transaction { private String hash; private String nonce; @@ -444,7 +448,7 @@ public void setV(Object v) { // this.v = v; // } - public String getyParity() { + public String getYParity() { return yParity; } @@ -617,9 +621,9 @@ public boolean equals(Object o) { if (getR() != null ? !getR().equals(that.getR()) : that.getR() != null) { return false; } - if (getyParity() != null - ? !getyParity().equals(that.getyParity()) - : that.getyParity() != null) { + if (getYParity() != null + ? !getYParity().equals(that.getYParity()) + : that.getYParity() != null) { return false; } if (getType() != null ? !getType().equals(that.getType()) : that.getType() != null) { @@ -683,7 +687,7 @@ public int hashCode() { result = 31 * result + (getR() != null ? getR().hashCode() : 0); result = 31 * result + (getS() != null ? getS().hashCode() : 0); result = 31 * result + BigInteger.valueOf(getV()).hashCode(); - result = 31 * result + (getyParity() != null ? getyParity().hashCode() : 0); + result = 31 * result + (getYParity() != null ? getYParity().hashCode() : 0); result = 31 * result + (getType() != null ? getType().hashCode() : 0); result = 31 * result + (getMaxFeePerGasRaw() != null ? getMaxFeePerGasRaw().hashCode() : 0); result = diff --git a/core/src/test/java/org/web3j/protocol/core/ResponseTest.java b/core/src/test/java/org/web3j/protocol/core/ResponseTest.java index e05c6bfc8f..828cf9dde5 100644 --- a/core/src/test/java/org/web3j/protocol/core/ResponseTest.java +++ b/core/src/test/java/org/web3j/protocol/core/ResponseTest.java @@ -1587,6 +1587,9 @@ void testEthTransactionResponseWithYParity() { "0x4869ff95a61ee1ded0b22e2d0e3f54f3199886a9f361e634132c95164bfc5129")))); EthTransaction ethTransaction = deserialiseResponse(EthTransaction.class); + assertEquals(ethTransaction.getTransaction().get().getFrom(), (transaction.getFrom())); + System.out.println("ethTransaction.getTransaction().get().getyParity()"); + System.out.println(ethTransaction.getTransaction().get().getYParity()); assertEquals(ethTransaction.getTransaction().get(), (transaction)); } @@ -2058,7 +2061,6 @@ void testEthCompileSolidity() { + " }\n" + " }\n" + " }\n" - + " }" + " }\n" + "}"); From f9d2348d691bae760d277813d176a94c1230366c Mon Sep 17 00:00:00 2001 From: Julius Lauterbach Date: Tue, 28 Apr 2026 17:49:02 +0200 Subject: [PATCH 7/8] fixes for RequestTest Signed-off-by: Julius Lauterbach --- .../web3j/protocol/parity/RequestTest.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/parity/src/test/java/org/web3j/protocol/parity/RequestTest.java b/parity/src/test/java/org/web3j/protocol/parity/RequestTest.java index dbecd1cd5d..1e8aef4c8a 100644 --- a/parity/src/test/java/org/web3j/protocol/parity/RequestTest.java +++ b/parity/src/test/java/org/web3j/protocol/parity/RequestTest.java @@ -274,7 +274,21 @@ public void testParityNewAccountFromWallet() throws Exception { web3j.parityNewAccountFromWallet(walletFile, "password").send(); verifyResult( - "{\"jsonrpc\":\"2.0\",\"method\":\"parity_newAccountFromWallet\",\"params\":[{\"address\":\"0x...\",\"id\":\"cab06c9e-79a9-48ea-afc7-d3bdb3a59526\",\"version\":1,\"crypto\":{\"cipher\":\"CIPHER\",\"ciphertext\":\"CIPHERTEXT\",\"cipherparams\":{\"iv\":\"IV\"},\"kdf\":\"KDF\",\"kdfparams\":{\"dklen\":32,\"n\":1,\"p\":10,\"r\":100,\"salt\":\"SALT\"},\"mac\":\"MAC\"}},\"password\"],\"id\":1}"); + "{\"jsonrpc\":\"2.0\",\"method\":\"parity_newAccountFromWallet\",\"params\":[{" + + "\"address\":\"0x...\"," + + "\"crypto\":{" + + "\"cipher\":\"CIPHER\"," + + "\"cipherparams\":{\"iv\":\"IV\"}," + + "\"ciphertext\":\"CIPHERTEXT\"," + + "\"kdf\":\"KDF\"," + + "\"kdfparams\":{\"dklen\":32,\"n\":1,\"p\":10,\"r\":100,\"salt\":\"SALT\"}," + + "\"mac\":\"MAC\"" + + "}," + + "\"id\":\"cab06c9e-79a9-48ea-afc7-d3bdb3a59526\"," + + "\"version\":1" + + "}," + + "\"password\"]," + + "\"id\":1}"); } public void testParityRemoveAddress() throws Exception { @@ -466,9 +480,12 @@ public void testTraceFilter() throws Exception { verifyResult( "{\"jsonrpc\":\"2.0\",\"method\":\"trace_filter\"," - + "\"params\":[{\"fromBlock\":\"earliest\",\"toBlock\":\"latest\"," + + "\"params\":[{" + "\"fromAddress\":[\"0xa9bebd4853ce06c3dc1b711bbafa1514ed5b5130\"]," - + "\"toAddress\":[\"0xB4d9b203d8D16f41916a62DEab83389cF2b7eeCb\"]}]," + + "\"fromBlock\":\"earliest\"," + + "\"toAddress\":[\"0xB4d9b203d8D16f41916a62DEab83389cF2b7eeCb\"]," + + "\"toBlock\":\"latest\"" + + "}]," + "\"id\":1}"); } From 0832ded41e042f8310a2bfd7f5c93748f34faf75 Mon Sep 17 00:00:00 2001 From: Julius Lauterbach Date: Wed, 29 Apr 2026 09:48:33 +0200 Subject: [PATCH 8/8] switched from treeToValue to convertValue Signed-off-by: Julius Lauterbach --- .../java/org/web3j/protocol/websocket/WebSocketService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java b/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java index 29149623f1..c329c36615 100644 --- a/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java +++ b/core/src/main/java/org/web3j/protocol/websocket/WebSocketService.java @@ -290,7 +290,7 @@ private void processRequestReply(String replyStr, JsonNode replyJson) throws IOE long replyId = getReplyId(replyJson); WebSocketRequest request = getAndRemoveRequest(replyId); try { - Object reply = objectMapper.treeToValue(replyJson, request.getResponseType()); + Object reply = objectMapper.convertValue(replyJson, request.getResponseType()); if (includeRawResponses && reply instanceof Response) { ((Response) reply).setRawResponse(replyStr); }