Skip to content

ACCEPT_SINGLE_VALUE_AS_ARRAY doesn't work on Guava ImmutableList #185

Closed
@JGergely

Description

@JGergely

Describe the bug
When defining a Guava ImmutableList on org.immutables.value.Value.Immutable objects to correctly deserialize both from a single JSON object and also from an array with the ACCEPT_SINGLE_VALUE_AS_ARRAY annotation on the field it fails to do so.

In case of using a java.util.List instead of the Guava type it works. Not sure if issue is within Jackson itself or somewhere else, please advise.

Version information
2.14

To Reproduce
To reproduce I created an Immutable type with a single list field which should accept both a single object and an array as a JSON input (set with ACCEPT_SINGLE_VALUE_AS_ARRAY).

@Value.Immutable
public interface ExampleInterface {
  @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
  ImmutableList<ExampleLine> getLines();
}

@Value.Immutable
public interface ExampleLineInterface {
  String getData();
}

class Scratch {
    public static void main(String[] args) {
         /*
            { 
                lines": 
                {
                    "data": "something"
                }
            }
         */
        String example = "{ " +
                "           \"lines\": \n" +
                "           {\n" +
                "             \"data\": \"something\"\n" +
                "           }" +
                "         }";
        try {
            Example actual = getObjectMapper().readValue(example, Example.class);
            System.out.println(actual);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    private static ObjectMapper getObjectMapper() {
        return JsonMapper.builder()
                .visibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
                .visibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY)
                .visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
                .propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
                .enable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)
                .enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY)
                .enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE)
                .enable(MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES)
                .disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)
                .disable(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)
                .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
                .addModule(new GuavaModule())
                .addModule(new FormattedNumberIdModule())
                .addModule(new JavaTimeModule())
                .addModule(new Jdk8Module())
                .addModule(new ParameterNamesModule())
                .build();

    }
}

throws

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.google.common.collect.ImmutableList<java.lang.Object>` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: (String)"{            "lines": 
           {
             "data": "something"
           }         }"; line: 2, column: 12] (through reference chain: com.picnic.supplierinterface.edeka.reddi.api.model.Example$Json["lines"])

while the same thing but with a java.util.List type:

@Value.Immutable
public interface ExampleInterface {
  @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
  List<ExampleLine> getLines();
}

deserializes correctly and prints:

Example{lines=[ExampleLine{data=something}]}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions