Skip to content

Map (de-)serialization bug #3011

@axlsml

Description

@axlsml

I encountered a problem when it comes to serialization of a Map<Type, String>. It is very easy to replicate the bug using junit.

Assume Type is a simple enum:

public enum Type {
    A, B
}

While these two tests are successful:

@SuppressWarnings("unchecked")
public class VavrBugTest {

    private final Map<Type, String> map = HashMap.of(Type.A, "A", Type.B, "B");

    @Test
    void simpleMapTest() {
        assertThat(map.get(Type.A)).isEqualTo(Option.of("A"));
        assertThat(map.get(Type.B)).isEqualTo(Option.of("B"));
    }

    @Test
    void deSerializedTest_sameProcess() throws IOException, ClassNotFoundException {
        serialize(map, "/tmp/map.bin");
        Map<Type, String> deSerialized = (Map<Type, String>) getDeSerialized("/tmp/map.bin");

        assertThat(deSerialized.get(Type.A)).isEqualTo(Option.of("A"));
        assertThat(deSerialized.get(Type.B)).isEqualTo(Option.of("B"));
    }

    private static Object getDeSerialized(String filename) throws IOException, ClassNotFoundException {
        FileInputStream fileIn = new FileInputStream(filename);
        ObjectInputStream in = new ObjectInputStream(fileIn);
        Object deSerialized = in.readObject();
        in.close();
        fileIn.close();
        return deSerialized;
    }

    private void serialize(Object object, String filename) throws IOException {
        FileOutputStream fileOut = new FileOutputStream(filename);
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        out.writeObject(object);
        out.close();
        fileOut.close();
    }
}

The next one will fail:

    @Test
    void deSerializedTest_previousProcess() throws IOException, ClassNotFoundException {
        // file should exist from a previous run of deSerializedTest_sameProcess
        Map<Type, String> deSerialized = (Map<Type, String>) getDeSerialized("/tmp/map.bin");

        assertThat(deSerialized.get(Type.A)).isEqualTo(Option.of("A")); // fails, although the map does contain the two entries
    }

The difference is that the serialization is done in one java process. And the de-serialization is done in a another process. The serialized file is not "compatible", so to say. This bug not seem to happen with e.g. String keys Map<String, String>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions