Skip to content

Unable to serialize top-level Java8 Stream #302

Open
@sunruh

Description

@sunruh

A Stream nested in another object is serialized using a value wrapper just as a collection or array, serializing a Stream directly fails when more than one element is available as it tries to write a second root. If the Stream emits only a single element serialization works but without wrapping:

public class StreamTest {
    private static final ObjectMapper OBJECT_MAPPER = new XmlMapper()
            .registerModule(new Jdk8Module());
    
    private static class StreamContainer {
        @JsonProperty
        private Stream<String> stream;
        public StreamContainer(Stream<String> stream) { this.stream = stream; }
    }

    @Test
    public void testTopLevelOneElement() throws JsonProcessingException {
        assertNotEquals("<Head>a</Head>",
                OBJECT_MAPPER.writeValueAsString(Stream.of("a")));
    }
    
    @Test
    public void testTopLevelTwoElements() throws JsonProcessingException {
        try {
            assertEquals("<Head><item>a</item><item>b</item></Head>",
                    OBJECT_MAPPER.writeValueAsString(Stream.of("a", "b")));
        } catch (JsonMappingException e) {
            fail("Trying to output second root?", e);
        }
    }
    
    @Test
    public void testNestedOneElement() throws JsonProcessingException {
        assertEquals("<StreamContainer><stream>a</stream></StreamContainer>",
                OBJECT_MAPPER.writeValueAsString(new StreamContainer(Stream.of("a"))));
    }
    
    
    @Test
    public void testNestedTwoElements() throws JsonProcessingException {
        assertEquals("<StreamContainer><stream>a</stream><stream>b</stream></StreamContainer>",
                OBJECT_MAPPER.writeValueAsString(new StreamContainer(Stream.of("a", "b"))));
    }
}

The root element name is Head for Stream serialization as it's determined from the actual class name ReferencePipeline$Head.

The cause lies in TypeUtil.isIndexedType(Class<?>) which just checks for Arrays and Collections and only if this returns true, a field name is written (and _nextName set).

It works for the nested Stream as _nextName is set due to the Stream being written as a field (multiple times).

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.16For issues planned for 2.16

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions