0

I am trying to serialise an object of the type HashMap<String, Object>. However, I get NotSerializableException at runtime. Here is the code that I use for serialization

public void WriteModel(String modelFile, HashMap<String, Object> o) {
    try {
        ObjectOutputStream os = new ObjectOutputStream (new FileOutputStream (modelFile));
        os.writeObject(o);
        os.close();
    }
    catch (Exception e) {
        System.out.println ("Error in saving model " + modelFile + ": " + e);
        e.printStackTrace();
    }
}

The HashMap has either an int as value or an object of the following type

public class suggestMenu implements Serializable {
    private static final long serialVersionUID = -8558253517294665710L;
    public List<Integer> suggestions = new ArrayList<Integer>();
    public int freq = 0; 
}

So basically all of the objects contained in HashMap are serializable. What is it that I am doing wrong? Has it something to do with the fact that HashMap contains more than one type? And what could be the possible way of serializing it, given that it is almost impossible to change its structure?

Here is the full stacktrace of the error

Error in saving model /home/ritesh/Documents/spell-checker/dict_ser.ser: java.io.NotSerializableException: spell.SpellCheckTrainer
java.io.NotSerializableException: spell.SpellCheckTrainer
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at java.util.HashMap.writeObject(HashMap.java:1129)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at spell.SpellCheckTrainer.WriteModel(SpellCheckTrainer.java:254)
at spell.SpellCheckTrainer.CreateDictionary(SpellCheckTrainer.java:246)
at spell.SpellCheckTrainer.main(SpellCheckTrainer.java:55)
ritesh
  • 229
  • 1
  • 5
  • 12
  • 2
    this can help http://stackoverflow.com/questions/7103611/hashmap-serializability – Dev. Joel Oct 11 '16 at 14:25
  • 2
    @ritesh it says `spell.SpellCheckTrainer`, is this class serializable? – Thomas Jungblut Oct 11 '16 at 15:08
  • 2
    I have a hunch: one of the values in the map is an inner class, which implicitly contains a reference to its enclosing class `SpellCheckTrainer`, which isn't serializable. Solution: use a static nested class instead. Don't serialize inner classes. – Stuart Marks Oct 11 '16 at 15:11
  • @Dev.Joel Thanks for pointing to the post! It helps me in better understanding HashMap's serialization process but I still do not quite understand why is it failing in this case and how could – ritesh Oct 11 '16 at 15:11
  • @ritesh every class being serialized has to be serializable. – Peter Lawrey Oct 11 '16 at 15:15
  • 1
    @ThomasJungblut, No SpellCheckTrainer is not serializable. So that is why it is failing. Thanks a lot for the help! – ritesh Oct 11 '16 at 15:18
  • @StuartMarks Yes you are absolutely right! I shall make that into a static class. Thanks a lot! – ritesh Oct 11 '16 at 15:22
  • Possible duplicate of [java.io.NotSerializableException](http://stackoverflow.com/questions/13895867/java-io-notserializableexception) – Tom Oct 11 '16 at 17:22

1 Answers1

0

HashMap can be serialized, but you have Object as values. These Objects might be NOT serializbale like your SpellCheckTrainer class. Make that class serializable you might be fine. Note: Sonarqube code analysis would still mark this as a CRITICAL issue with squid:S1948

Markus
  • 1,887
  • 18
  • 23