vavr icon indicating copy to clipboard operation
vavr copied to clipboard

Map (de-)serialization bug

Open axlsml opened this issue 7 months ago • 1 comments

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>.

axlsml avatar Apr 02 '25 18:04 axlsml