FasterXML / jackson-dataformat-xml

Extension for Jackson JSON processor that adds support for serializing POJOs as XML (and deserializing from XML) as an alternative to JSON
Apache License 2.0
561 stars 221 forks source link

Cannot construct instance of `PEPSchema.MEMBER` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Yes1') #655

Closed mbradshawUtah closed 3 weeks ago

mbradshawUtah commented 1 month ago

JacksonXmlUtil.txt APPLICATION_FULL_TYPE.txt SECTION_B_TYPE.txt MEMBER.txt

Looks similar to this issue, but I am still having this issue even though I am using 2.17.1 https://github.com/FasterXML/jackson-dataformat-xml/issues/646

I am expecting Yes1 for all 3 tests.

ERROR:

About to start 1st test.
1st Test result is: Yes1

About to start 2nd test.
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `pepschema.MEMBER` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Yes1')
 at [Source: (StringReader); line: 1, column: 60] (through reference chain: pepschema.SECTION_B_TYPE["HOUSEHOLD_MEMBER"]->java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1754)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1379)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromString(StdDeserializer.java:311)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1588)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:197)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:361)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:246)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:30)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
    at com.fasterxml.jackson.dataformat.xml.deser.XmlDeserializationContext.readRootValue(XmlDeserializationContext.java:104)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3848)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3816)
    at util.JacksonXmlUtil2.xmlStringToObject(JacksonXmlUtil.java:117)
    at util.JacksonXmlUtil2.main(JacksonXmlUtil.java:83)

About to start 3rd test.
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `pepschema.MEMBER` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Yes1')
 at [Source: (StringReader); line: 1, column: 98] (through reference chain: pepschema.APPLICATION_FULL_TYPE["SECTION_B"]->pepschema.SECTION_B_TYPE["HOUSEHOLD_MEMBER"]->java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1754)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1379)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromString(StdDeserializer.java:311)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1588)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:197)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:361)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:246)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:30)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
    at com.fasterxml.jackson.dataformat.xml.deser.XmlDeserializationContext.readRootValue(XmlDeserializationContext.java:104)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3848)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3816)
    at util.JacksonXmlUtil2.xmlStringToObject(JacksonXmlUtil.java:117)
    at util.JacksonXmlUtil2.main(JacksonXmlUtil.java:96)
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.17.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.datatype/jackson-datatype-jdk8 -->
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
    <version>2.17.1</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.17.1</version>
</dependency>

CODE:

mbradshawUtah commented 1 month ago

If I just do MEMBER.class and have 1 household member then It deserializes fine. If I do the sectionB and the sectionb class I get the same error. Something with List causing an issue?

cowtowncoder commented 1 month ago

Added a label noting that we'd need an actual manageable test case -- definitions and output above is way too big to help with reproduction, unfortunately.

mbradshawUtah commented 1 month ago

Added a label noting that we'd need an actual manageable test case -- definitions and output above is way too big to help with reproduction, unfortunately.

I have attached 4 smaller files for the test. What is happening is that Reading HOUSEHOLD_MEMBER by itself works and loads correctly into the java object.

Doesn't matter if there is 1 household member in section b or multiple household members in section b both will result in the same error. Same thing happens when section b is in the Applicaiton tags the surrounding object application full type that also fails. I expect all 3 tests to return yes1.

cowtowncoder commented 1 month ago

Ok this is more useful (thank you!), but what is eventually needed is a unit test to reproduce the problem.

Still maybe someone has time to look into this and smaller files sound useful. I don't think I will have time to look into this on short term but others might.

cowtowncoder commented 1 month ago

Oh: forgot to mention that it may make sense to try this with 2.18.0-SNAPSHOT versions. Constructor detection has been rewritten in 2.18 branch and that might relevant, wrt exception message (if this is due to incorrect detection of Constructor to use).

mbradshawUtah commented 1 month ago

image So apparently the issue is that HOUSEHOLD_MEMBER List doesn't use a wrapper so specifying that fixes this issue. Not sure why jaxb is generating the class like that.
@JacksonXmlElementWrapper(useWrapping=false)

mbradshawUtah commented 3 weeks ago

JacksonXmlModule xmlModule = new JacksonXmlModule(); xmlModule.setDefaultUseWrapper(false); XmlMapper xmlMapper = new XmlMapper(xmlModule);

This is resolved once I used this code above. Apparently since Jaxb uses lists we have to disable the defaultusewrapper.

cowtowncoder commented 3 weeks ago

JAXB defaults are indeed different: if no annotations/configuration is changed, JAXB defaults to "unwrapped" Lists. Jackson defaults to wrapped Lists and requires configuration or annotations to disable it.