Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MismatchedInputException encountered while deserializing XML to an Enum type using a factory method #682

Closed
WannabeSoftwareEngineer opened this issue Nov 7, 2024 · 6 comments
Labels
2.18 Issues planned at earliest for 2.18
Milestone

Comments

@WannabeSoftwareEngineer
Copy link

Hello,
I'm trying to serialize an Enum type to XML, then read it back, but I get an input mismatch error related to JsonCreator.

Could someone provide insights into why deserialization fails?

Any help would is appreciated. Thank you.

Error

com.fasterxml.jackson.databind.exc.MismatchedInputException: Input mismatch reading Enum `com.xxx.yyy.Country`: properties-based `@JsonCreator` ([method com.xxx.yyy.Country#fromValue(java.lang.String)]) expects String Value, got Object value (`JsonToken.START_OBJECT`)

Test

@Test
void aTest() throws JsonProcessingException {
    XmlMapper xmlMapper = new XmlMapper();
    
    String s = xmlMapper.writeValueAsString(Country.ITALY);
    assertThat(s).isEqualTo("<Country>Italy</Country>");
    
    Country country = xmlMapper.readValue(s, Country.class);
    assertThat(country).isEqualTo(Country.ITALY); // fails with the error reported above
}

Country.java

public enum Country {
    ITALY("Italy"),
    NETHERLANDS("Netherlands");

    private String value;

    Country(String value) {
        this.value = value;
    }

    @JsonValue
    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }

    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static Country fromValue(String value) {
        for (Country b : Country.values()) {
            if (b.value.equals(value)) {
                return b;
            }
        }
        throw new IllegalArgumentException("Unexpected value '" + value + "'");
    }
}

library: com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.17.1

original report submitted here: https://groups.google.com/g/jackson-user/c/xXgyb_uKbGg/m/fCcNz9WOCAAJ

@pjfanning
Copy link
Member

Another issue with a similar JsonCreator annotation - FasterXML/jackson-databind#4785

@cowtowncoder
Copy link
Member

Probably not same root cause, but good to reference nonetheless. That one seems like invalid issue (but understandable; 2.18 changing behavior but in this case -- seems to me -- fixing it).

@cowtowncoder
Copy link
Member

Note to self: jackson-databind EnumDeserializer has handling in

    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
    {
         // ....
        if (p.hasToken(JsonToken.VALUE_STRING)) {
            return _fromString(p, ctxt, p.getText());
        }
         // ....
        // 29-Jun-2020, tatu: New! "Scalar from Object" (mostly for XML)
        if (p.isExpectedStartObjectToken()) {
            return _fromString(p, ctxt,
                    ctxt.extractScalarFromObject(p, this, _valueClass));
        } 
    }

which handles special XML-ness aspects. But this is probably not handled for factory case, for some reason.

@cowtowncoder cowtowncoder added the 2.18 Issues planned at earliest for 2.18 label Nov 9, 2024
@WannabeSoftwareEngineer
Copy link
Author

WannabeSoftwareEngineer commented Nov 20, 2024

@cowtowncoder

Do you have any suggestions for a workaround or where I should be looking at to check if I can add one temporary?
At the moment, we can't change the type, e.g. Country.java, because it is auto-generated and we can't change the template without undertaking a massive refactoring of our codebase

@cowtowncoder
Copy link
Member

@WannabeSoftwareEngineer No, unfortunately I can't think of an obvious work-around here.

@cowtowncoder cowtowncoder added this to the 2.18.2 milestone Nov 25, 2024
@cowtowncoder cowtowncoder changed the title MismatchedInputException encountered while deserializing XML to an Enum type using a factory method MismatchedInputException encountered while deserializing XML to an Enum type using a factory method Nov 25, 2024
@cowtowncoder
Copy link
Member

Fixed via FasterXML/jackson-databind#4807 (and added tests to verify via #685). Will be in 2.18.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.18 Issues planned at earliest for 2.18
Projects
None yet
Development

No branches or pull requests

3 participants