4

We are using HashMap in JDK 1.7 and I face some issue during the code review with SonarQube.

Please consider below samples:

public class SerializationTest implements  Serializable {

   private Map<String,String> test1=new HashMap<>(); //Serializeable
   private Map<ANEnum,String> test2=new HashMap<>(); //Serializeable
   private Map<String,ASerializeableObject> test3=new HashMap<>();  //Serializeable 

   private Map<String,Map<String,String>> test4=new HashMap<>(); //Not Serializeable
   private Map<ANEnum,Map<String,String>> test5=new HashMap<>(); //Not Serializeable
   private Map<String,Map<String, ASerializeableObject>> test6=new HashMap<>(); //Not Serializeable

The Sonar mark last three HashMaps as not serializeable. The Sonar error is (Make "test4" transient or serializable)

As far as I guessed the HashMap is serializeable if its key and value are serializeable. But it seems that if I set a HashMap value as another HashMap, the original HashMap will not be serializeable at all.

Is this Sonar Issue correct ?! If it is how can I fix it ?!

user207421
  • 305,947
  • 44
  • 307
  • 483
Alireza Fattahi
  • 42,517
  • 14
  • 123
  • 173
  • 1
    To test if something is serializable, serialize it. Sonar can't know if what your map actually contains at runtime is serializable. And if you ask about a Sonar violation, post the exact and complete message and rule name. – JB Nizet Jan 15 '17 at 09:06
  • Rather poor effort on Sonarqube's part, given that the variable is declared and initialized in the same statement. – user207421 Jan 15 '17 at 09:27
  • @EJP SOnar can't *guarantee* that the map is serializable, since it contains instances of `Map`, and `Map` isn't Serializable. At runtime, it might be, but at compile time, you have no guarantee that the inner maps are serializable. – JB Nizet Jan 15 '17 at 09:47
  • @JBNizet The rule name is: `Fields in a "Serializable" class should either be transient or serializable` (squid:S1948 ). – Alireza Fattahi Jan 15 '17 at 12:15
  • Dear @JBNizet it seems that for three first example, the Sonar guarantee the serialization, as you will not see a bug report there :) This may be a bug in sonar. Because, Sonar guarantees that `Map` is serializeable (You will see no error in code review) , but when you replace that `ASerializeableObject` with `Map` which is already mentioned to be `serializeable`, the final result `Map>` is marked to be not `serializeable`. – Alireza Fattahi Jan 15 '17 at 12:25

1 Answers1

8

Let's see each line, one by one:

private Map<String,String> test1=new HashMap<>();

The key type, String, is serializable. The value type, String, is serializable. The concrete Map type, HashMap, is serializable. So everything is serializable.

private Map<ANEnum,String> test2=new HashMap<>(); 

The key type, ANEnum, is serializable. The value type, String, is serializable. The concrete Map type, HashMap, is serializable. So everything is serializable.

private Map<String,ASerializeableObject> test3=new HashMap<>();

The key type, String, is serializable. The value type, ASerializeableObject, is serializable. The concrete Map type, HashMap, is serializable. So everything is serializable.

private Map<String,Map<String,String>> test4=new HashMap<>();

The key type, String, is serializable. The concrete Map type, HashMap, is serializable. But the value type, Map, is not necessarily serializable. Some concrete implementations of Map (like HashMap), are serializable. Some others are not. So Sonar can't guarantee that this field is serializable, and issues a warning. If you're sure that you will only store serializable maps as values, no problem. If you store non-serializable maps, then the serialization will fail at runtime.

private Map<ANEnum,Map<String,String>> test5=new HashMap<>(); //Not Serializeable

Same explanation as before

private Map<String,Map<String, ASerializeableObject>> test6=new HashMap<>();

Same explanation as before

Remember that Sonar is only a tool, which can sometimes help, and sometimes get in the way. You should be in control, and decide if a warning should make you change things, or not.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • _Some concrete implementations of Map (like HashMap), are serializable. Some others are not ...._ This is what I didn't know! Thanks! – Alireza Fattahi Dec 07 '19 at 04:31