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

Can not deserialize unwrapped list when @JacksonXmlProperty localName matches @JacksonXmlRootElement localName #86

Closed
spoon16 opened this issue Dec 19, 2013 · 9 comments
Milestone

Comments

@spoon16
Copy link

spoon16 commented Dec 19, 2013

Please refer to http://stackoverflow.com/questions/20673153/using-jackson-to-deserialize-a-collection-of-children-with-the-same-type-as-the

I can not figure out how to deserialize a document like this:

<test id="0">
    <test id="0.1">
        <test id="0.1.1" />
    </test>
    <test id="0.2" />
    <test id="0.3">
        <test id="0.3.1" />
    </test>
</test>

Where each test element is deserialized into a simple POJO.

Here is the code I am dealing with.

public class UnitTest {

  @Test
  public void test() throws Exception {
    final ObjectMapper mapper = new XmlMapper();

    final XmlTest before =
        new XmlTest("0", Lists.newArrayList(new XmlTest("0.1", null),
            new XmlTest("0.2", Lists.newArrayList(new XmlTest("0.2.1", null)))));
    final String xml = mapper.writeValueAsString(before);
    System.out.println(xml);
    final XmlTest after = mapper.readValue(xml, XmlTest.class);
  }

  @JacksonXmlRootElement(localName = "test")
  public static class XmlTest {
    @JacksonXmlProperty(localName = "id", isAttribute = true)
    private String id;
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "test")
    private List<XmlTest> children;

    public XmlTest() {}

    public XmlTest(final String id, final List<XmlTest> children) {
      this.id = id;
      this.children = children;
    }
  }

}

My imported dependencies:

    compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: jacksonVersion
    compile group: 'com.fasterxml.jackson.jaxrs', name: 'jackson-jaxrs-xml-provider', version: jacksonVersion

    jacksonVersion=2.2.+
@spoon16
Copy link
Author

spoon16 commented Dec 19, 2013

com.fasterxml.jackson.databind.JsonMappingException: Current state not XML_START_ELEMENT (1) but 6 (through reference chain api.core.jasper.XmlTest["test"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:197)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1311)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:297)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
    at com.fasterxml.jackson.dataformat.xml.deser.WrapperHandlingDeserializer.deserialize(WrapperHandlingDeserializer.java:109)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)
    at api.core.jasper.UnitTest.test(UnitTest.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.IllegalStateException: Current state not XML_START_ELEMENT (1) but 6
    at com.fasterxml.jackson.dataformat.xml.deser.XmlTokenStream.repeatStartElement(XmlTokenStream.java:228)
    at com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser.addVirtualWrapping(FromXmlParser.java:280)
    at com.fasterxml.jackson.dataformat.xml.deser.WrapperHandlingDeserializer._configureParser(WrapperHandlingDeserializer.java:140)
    at com.fasterxml.jackson.dataformat.xml.deser.WrapperHandlingDeserializer.deserialize(WrapperHandlingDeserializer.java:108)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:230)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:207)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:464)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:107)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:295)
    ... 28 more

@spoon16 spoon16 closed this as completed Dec 19, 2013
@spoon16 spoon16 reopened this Dec 19, 2013
@spoon16
Copy link
Author

spoon16 commented Dec 20, 2013

I updated the stackoverflow question with an answer. I was able to work around this with a custom deserializer. I do think there might be a bug here though.

@cowtowncoder
Copy link
Member

Thanks -- it should be possible to add a unit test, see what is causing the issue here.

@jwgmeligmeyling
Copy link

Can confirm issue, any idea how this could be solved?

cowtowncoder added a commit that referenced this issue Dec 26, 2015
…ason, as opposed to failing due to missing test method)
@cowtowncoder
Copy link
Member

Unfortunately this test still fails, despite fixes that seemed like they would be relevant (esp #177). Still hope to figure it out eventually.

@Pytry
Copy link

Pytry commented Nov 14, 2019

I'm facing this same issue in version 2.10.0. Seems like it is trying to set private List<XmlTest> children to a single XmlTest instance instead of a List<XmlTest>.

@Pytry
Copy link

Pytry commented Nov 15, 2019

I did some experimenting, and created some more examples that demonstrate this behavior.

https://github.com/Pytry/can-not-deserialize-unwrapped-list-when-jacksonxmlproperty-localname-matches-j

This does NOT assert that the described and tested behaviour is correct or a bug.

  1. If the localname of the root element in the actual XML is the same as any of it's children,
    then jackson cannot deserialize, regardless of how the class is annotated.

  2. If the annotated class is given the same localname as any of it's fields,
    jackson will still deserialize an XML who's actual root element name does not
    match the annotated class.

  3. If the XML documents main root element is different than it's children,
    then it's children may have children with a localname that is the same as their parent
    so long as the parent is not the root of the entire document.

@cowtowncoder
Copy link
Member

I fixed #393, which is probably related, but unfortunately that did not yet resolve this issue.
Hoping to have a look to see if I can fix it.

@cowtowncoder cowtowncoder changed the title Can not deserialize unwrapped list when @JacksonXmlProperty localName matches @JacksonXmlRootElement localName Can not deserialize unwrapped list when @JacksonXmlProperty localName matches @JacksonXmlRootElement localName May 12, 2020
@cowtowncoder cowtowncoder added this to the 2.12.0 milestone May 13, 2020
cowtowncoder added a commit that referenced this issue May 13, 2020
@cowtowncoder cowtowncoder modified the milestones: 2.12.0, 2.11.1 May 13, 2020
@cowtowncoder
Copy link
Member

Initially was planning to fix for 2.12 only, but as per user request, backport in 2.11 for 2.11.1.

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

No branches or pull requests

4 participants