vavr-io / vavr-jackson

Jackson datatype module for Vavr
Apache License 2.0
97 stars 35 forks source link

Cannot deserialize JSON array to vavr List, using JavaType ObjectMapper API #189

Open skapral opened 2 years ago

skapral commented 2 years ago

The version is 0.10.3

Minimal example for reproducing the issue is:

package com.skapral.test;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import io.vavr.collection.List;
import io.vavr.jackson.datatype.VavrModule;

import java.lang.reflect.Method;

class XY {
    private int x, y;

    public XY() {
    }

    public XY(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

public class Main2 {
    private static final Method sample;

    static {
        try {
            sample = Main2.class.getDeclaredMethod("sample", List.class);
        } catch(Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    public static void sample(List<XY> arg) {}

    public static void main(String... args) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new VavrModule());

        String s = "[{\"x\":1,\"y\":2},{\"x\":3,\"y\":4}]";

        JavaType a = TypeFactory.defaultInstance().constructType(sample.getGenericParameterTypes()[0]);
        try {
            var list = mapper.readValue(s, a);
        } catch(Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

Attempt to run this code will cause

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `byte` from Object value (token `JsonToken.START_OBJECT`)

Some context on how the issue was bumped into, can be found here. I was using vavr + vavr-jackson + spring AMQP for messaging, and faced the issue when made attempt to deserialize AMQP message with JSON array payload. Spring AMQP does deserialization the same way, like it is done in example above.