Skip to content

SnakeCaseStrategy causes unexpected MismatchedInputException during deserialization #3368

@sszuev

Description

@sszuev

The following test (TestStructureWithSnakeNames.java.txt) works fine in 2.12.0 :

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import java.util.Map;

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class TestStructure {
    private String timeZone;
    private String utcZone;

    @JsonProperty("time_zone")
    private void unpackTimeZone(Map<String, String> timeZone) {
        this.setTimeZone(timeZone.get("name"));
        this.setUtcZone(timeZone.get("utc_zone"));
    }

    public String getTimeZone() {
        return this.timeZone;
    }

    public String getUtcZone() {
        return this.utcZone;
    }

    public void setTimeZone(String timeZone) {
        this.timeZone = timeZone;
    }

    public void setUtcZone(String utcZone) {
        this.utcZone = utcZone;
    }

    public static class DeserializationTest {
        public static void main(String... args) throws Exception {
            ObjectMapper objectMapper = new ObjectMapper();
            System.out.println(objectMapper.version());
            String test = "    {\n" +
                    "      \"time_zone\": {\n" +
                    "        \"name\": \"XXX\",\n" +
                    "        \"utc_zone\": \"ZZZ\"\n" +
                    "      }\n" +
                    "    }";
            TestStructure res = objectMapper.readerFor(new TypeReference<TestStructure>() {
            }).readValue(test);
            assert "XXX".equals(res.getTimeZone()) : "wrong time"; // use `java -ea ...` when run
            assert "ZZZ".equals(res.getUtcZone()) : "wrong zone";
            System.out.println("DONE");
        }
    }
}

But after switching to 2.12.1 (and later) I see the error :

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: (String)"    {
      "time_zone": {
        "name": "XXX",
        "utc_zone": "ZZZ"
      }
    }"; line: 2, column: 20] (through reference chain: TestStructure["time_zone"])
	at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
	at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1741)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1515)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1420)
	at com.fasterxml.jackson.databind.DeserializationContext.extractScalarFromObject(DeserializationContext.java:932)
	at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:62)
	at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:313)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
	at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2051)
	at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1492)
	at TestStructure$DeserializationTest.main(TestStructure.java:47)

Since the similar test with normal names (TestStructureWithNormalNames.java.txt) works well in 2.12.0, 2.12.1 and 2.13.1, I suspect this behavior could be a bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions