Skip to content

Accept JsonTypeInfo.As.WRAPPER_ARRAY with no second argument to deserialize as "null value" #2467

@colltoaction

Description

@colltoaction

Hi!

At RSK we're trying to map Ethereum PUB-SUB JSON-RPC API requests.

We got stuck trying to map the eth_subscribe parameters, here are two examples:

{"id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
{"id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "...", ...]}]}

As you can see, the params type is given by the first parameter, so we thought we could do something like this:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_ARRAY)
@JsonSubTypes({
        @JsonSubTypes.Type(value = EthSubscribeNewHeadsParams.class, name = "newHeads"),
        @JsonSubTypes.Type(value = EthSubscribeLogsParams.class, name = "logs"),
})
public class EthSubscribeParams {

While everything worked perfectly for logs, the AsArrayTypeDeserializer wasn't able to deserialize newHeads because it doesn't have an object with extra parameters. It fails on:

com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of co.rsk.rpc.modules.eth.subscribe.EthSubscribeNewHeadsParams out of END_ARRAY token
 at [Source: java.io.ByteArrayInputStream@cb0ed20; line: 1, column: 72] (through reference chain: co.rsk.rpc.modules.eth.subscribe.EthSubscribeRequest["params"])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
    at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1075)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:186)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:150)
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:116)
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromObject(AsArrayTypeDeserializer.java:61)

We then tried to implement DeserializationProblemHandler#handleUnexpectedToken and build the expected instance ourselves, but the workaround doesn't work because the code expects p.nextToken() != JsonToken.END_ARRAY even if the instance was created successfully.

Now we'll try a different approach without JsonTypeInfo.As.WRAPPER_ARRAY, but it would be amazing if this simple case could be handled. I would suggest treating no value as {}.

If you would be interested in me contributing this feature, please advise how I could approach it. I'd be happy to send a PR.

Cheers!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions