'How can I avoid a NullPointerException when deserializing a HashMap whose keys/value reference the map?

I've created a graph class that I'd like to make serializable. The graph tracks its nodes in a HashMap. The keys to this map reference nodes, and the nodes reference the graph.

When you deserialize a HashMap, the key object's hashCode() method gets called. That method references objects that might not be finished deserializing yet, so it causes a NullPointerException.

I've created a minimal example. It's obviously stupid, but it's the smallest example where I can guarantee that hashCode() references an object that is not done deserializing (in this case, the HashMap itself).

package sgware;

import java.io.*;
import java.util.HashMap;

public class Main {
    
    public static class Graph implements Serializable {
        
        public final HashMap<Key, Node> nodes = new HashMap<>();
    }
    
    public static class Node implements Serializable {
        
        public final Graph graph;
        
        public Node(Graph graph) {
            this.graph = graph;
        }
    }
    
    public static class Key implements Serializable {
        
        public final Node node;
        
        public Key(Node node) {
            this.node = node;
        }
        
        @Override
        public int hashCode() {
            // I know this is a bad hashCode; the point is to force a reference
            // to the still-deserializing HashMap.
            return node.graph.nodes.size();
        }
    }

    public static void main(String[] args) throws Exception {
        Graph graph = new Graph();
        Node node = new Node(graph);
        graph.nodes.put(new Key(node), node);
        try(ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("file.obj")))) {
            out.writeObject(graph);
        }
        try(ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("file.obj")))) {
            in.readObject();
        }
    }
}

Looking for advice on how to make something like this serializable.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source