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

Deserialization of an empty list (with empty XML tag) results in null #124

Closed
danblack opened this issue Nov 8, 2014 · 22 comments
Closed
Milestone

Comments

@danblack
Copy link

danblack commented Nov 8, 2014

XML serialization/deserialization of an empty array is not working consistently (unlike JSON) .
When I try to deserialize an empty list from xml I get a null list (but I except to get an empty list).
I don't have this problem with JSON.

Library version 2.4.3, jdk 8.0_25
Here is my example

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Test {

    @XmlRootElement(name = "root")
    public static class TestList {
        @XmlElement(name = "list")
        public List<Object> list;
    }

    public static void main(String[] args) throws IOException {
        // XML
        XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.registerModule(new JaxbAnnotationModule());
        TestList originalObject = new TestList();
        originalObject.list = new ArrayList<Object>();
        String xml = xmlMapper.writeValueAsString(originalObject);
        System.out.println(xml); // print <root xmlns=""><list></list></root>
        TestList actualObject = xmlMapper.readValue(xml, TestList.class);
        System.out.println(actualObject.list);  // print null

        // JSON
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JaxbAnnotationModule());
        String json = objectMapper.writeValueAsString(originalObject);
        System.out.println(json); // print {"list":[]}
         actualObject = objectMapper.readValue(json, TestList.class);
        System.out.println(actualObject.list); // print []
    }
}
@agibalov
Copy link

Just faced the same issue. Are there any plans to make this behavior configurable?

@cowtowncoder
Copy link
Member

At first I'd need to understand what the problem is: most likely it is due to convoluted way XML stream is read, to try to determine whether an element would be considered equivalent to JSON Object or Array.

Another thing to try to is to see if 2.5.0 makes any difference; there was at least one fix related to List/array handling.

@agibalov
Copy link

Just tried 2.5.0:

@Test
public void canDeserializeEmptyCollection() throws IOException {
    String xml =
            "<PersonList>" +
                "<people />" +
            "</PersonList>";

    XmlMapper xmlMapper = new XmlMapper();
    PersonList personList = xmlMapper.readValue(xml, PersonList.class);
    assertNotNull(personList.people); // <--- HERE
    assertEquals(0, personList.people.size());
}

public static class PersonList {
    @JacksonXmlElementWrapper(localName = "people")
    @JacksonXmlProperty(localName = "person")
    public List<Person> people;
}

public static class Person {
    public String name;
}

personList.people is still null.

@cowtowncoder
Copy link
Member

Thank you for verifying this.

So, it is a bug, not an intentional deviation from JSON handling.

@avianey
Copy link

avianey commented Oct 21, 2015

any new on this, still the same issue in the latest jackson release...

@ilgrosso
Copy link

Just verified with 2.6.3 - still the same...

@rajeshksv
Copy link

Any update on the same ?

@cowtowncoder
Copy link
Member

No news here.

@kmp3325
Copy link

kmp3325 commented Jun 10, 2016

Just ran into this problem myself...If you reverse the annotations it seems to work without issue:

    @JacksonXmlElementWrapper(localName = "person")
    @JacksonXmlProperty(localName = "people")
    public List<Person> people;

@cowtowncoder cowtowncoder changed the title Deserialization an empty list Deserialization if an empty list (with empty XML tag) results in null Jun 11, 2016
cowtowncoder added a commit that referenced this issue Jun 11, 2016
@cowtowncoder
Copy link
Member

Yes, I can reproduce this now. Whether empty element is expressed as <list/> or <list></list> makes no difference, and having white space (<list> </list>) actually produces an error since white space is expressed as String token (which it could be).

@ssmoss
Copy link

ssmoss commented Oct 18, 2016

Just curious if there is any ETA on a fix for this? Thanks.

@lightbringer
Copy link

My workaround in 2.8.9 was a readResolve method that checks if any of the collections in the class were null and respectively created a new collection.

@newtechfellas
Copy link

Any solution to this? I see the same problem. I upgraded from 2.1.1 to 2.6.7. 2.1.1 was working. upgrade broke the tests while deserializing empty xml element into a array list property

@mykmaley
Copy link

mykmaley commented Nov 1, 2018

Still suffering with this bug in 2.8.10. Any ETA?

Edit: Thought this was closed, but it was the related bugs. Still waiting for a fix for this bug.

@mschne
Copy link

mschne commented Feb 8, 2019

We also encountered this problem in our project. While trying to fix this i noticed that there is a feature FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL which is enabled by default. I tried to disable it but it did not make any difference in the above testcase.

XmlMapper xmlMapper = new XmlMapper();
xmlMapper.disable(FromXmlParser.Feature.EMPTY_ELEMENT_AS_NULL);

Is this feature related to this problem? How can we make it work?

@KainWhite
Copy link

Still this same issue in 2.10.0. Maybe someday...

@henrik242
Copy link

henrik242 commented Jan 13, 2020

This might be fixed in 2.10.2, see #378

@cowtowncoder
Copy link
Member

@henrik242 Unfortunately that is bit different problem.

However! There is actually a way to make it work by using (relatively) new "config overrides" with null-handling override. Specifically, adding this:

       xmlMapper.configOverride(List.class)
            .setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));

will then convert logical null value into "empty", and for Lists that would be empty List.

@cowtowncoder cowtowncoder added this to the 2.12.0 milestone Jun 6, 2020
@cowtowncoder
Copy link
Member

Fixed for 2.12.0

cowtowncoder added a commit that referenced this issue Jun 6, 2020
@henrik242
Copy link

henrik242 commented Oct 13, 2020

FasterXML/jackson-module-kotlin#396 might be related to this (jackson 2.12.0-rc1 regression)

@cowtowncoder cowtowncoder changed the title Deserialization if an empty list (with empty XML tag) results in null Deserialization of an empty list (with empty XML tag) results in null Dec 11, 2020
@cowtowncoder
Copy link
Member

@henrik242 If there is a remaining problem with this issue on 2.12.1, reproducible with just this module (there are some issues related to Kotlin module which gets trickier), could you please file a new issue with reproduction?
I usually do not reopen old issue if (assumed) fix has been released in a production version as that complicates release notes.

@henrik242
Copy link

@cowtowncoder I've only managed to reproduce it with the kotlin and xml module together. So I'll just stick with FasterXML/jackson-module-kotlin#396 :)

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