Checker Serialization

belongs to group Basic
Identify serialization problems

Frameworks supported by this checker

  • java up to 11
  • android up to API level 28
  • dotnet

Warnings generated by this checker

  • MissingSerialVersionFieldWarning: missing or incorrect serialVersionUID in serializable class [ CWE913 ]
  • NonSerializableElementsOfFieldWarning: a non-transient field of a serializable class might hold a map or collection whose elements might be non-serializable [ CWE913 ]
  • NonSerializableFieldWarning: a non-transient field of a serializable class might hold a non-serializable value [ CWE913 ]
  • NonSerializableOuterClassWarning: an inner non-static serializable class has a non-serializable outer class [ CWE913 ]
  • UnexpectedSerialVersionFieldWarning: a serialVersionUID field is defined where it is not expected [ CWE913 ]

Options accepted by this checker

  • containersAreSerializable: assume that container classes from the standard library are always serializable
    Most containers, such as collections, lists and maps, are serializable, but that depends on the specific concrete class used for their implementation. This hypothesis instructs Julia to assume that only serializable containers are used

Annotations understood by this checker

  • none


Description

Serialization allows one to dump an object into a file and recover (deserialize) it later. For this to work, Java requires the class of the object to implement the java.io.Serializable interface. Moreover, all instance non-transient fields of the class must be serializable themselves. For inner non-static classes, also the outer class must be serializable. In order to distinguish dumps of objects for distinct versions of the same class, it is required that serializable classes define a static field containing the serial version of the class.

Action: Guarantee that all instance non-transient fields of a serializable class are themselves serializable. Make inner serializable classes have a serializable outer class, or make them static. Add a long serialVersionUID field to serializable classes.

Serialization allows one to dump an object into a file and recover (deserialize) it later. For this to work, Java requires the class of the object to implement the System.Runtime.Serialization.ISerializable interface. Moreover, all instance non-transient fields of the class must be serializable themselves. For inner non-static classes, also the outer class must be serializable. In order to distinguish dumps of objects for distinct versions of the same class, it is required that serializable classes define a static field containing the serial version of the class.

Action: Guarantee that all instance non-transient fields of a serializable class are themselves serializable. Make inner serializable classes have a serializable outer class, or make them static. Add a long serialVersionUID field to serializable classes.

Examples

Consider the following classes:

import java.io.Serializable;

public class SerializationTest implements Serializable {
  private static final long serialVersionUID = -8282042466563875052L;
  private final Object f;
  private final C.Inner inner;
	
  public SerializationTest(Object f) {
    this.f = f;
    this.inner = new C().new Inner();
  }
}

and

import java.io.Serializable;

class C {
  public class Inner implements Serializable {}
}

This checker issues the following warnings:

C.java:4: [Serialization: MissingSerialVersionUIDWarning] Serializable class C$Inner should have a final static long serialVersionUID field
C.java:4: [Serialization: NonSerializableOuterClassWarning] Serializable non-static inner class C$Inner has a non-serializable outer class
SerializationTest.java: [Serialization: NonSerializableFieldWarning] Field SerializationTest.f might possibly hold a non-serializable value

since the inner serializable class C.Inner misses the serialVersionUID field and has a non-serializable outer class. Moreover, field SerializationTest.f might hold any object, also non-serializable objects, which is not correct for an instance field of a serializable class.

In this example, the programmer should add the missing serialVersionUID field, make the inner class static and restrict the possible values for field SerializationTest.f, as follows:

import java.io.Serializable;

public class SerializationTest implements Serializable {
  private static final long serialVersionUID = -8282042466563875052L;
  private final Object f;
  private final C.Inner inner;
	
  public SerializationTest(Serializable f) {
    this.f = f;
    this.inner = new C.Inner();
  }
}
import java.io.Serializable;

class C {
  public static class Inner implements Serializable {
    private static final long serialVersionUID = 7979349187288425675L;
  }
}

Consider the following classes:

using System.Runtime.Serialization;
namespace DocumentationExamples
{
    public class Serialization : ISerializable
    {
        public static void Main(string[] args)
        { }

        private readonly object f;
        private readonly SerializationC.Inner inner;

        public Serialization(object f)
        {
            this.f = f;
            inner = new SerializationC.Inner();
        }
        public void GetObjectData(SerializationInfo info, StreamingContext context) { }
    }
    public class SerializationC
    {
        public class Inner : ISerializable
        {
            public void GetObjectData(SerializationInfo info, StreamingContext context) { }
        }
    }
    
}

This checker issues the following warnings:

DocumentationExamples.cs: [Serialization: NonSerializableFieldWarning] Field "f" might possibly hold a non-serializable value DocumentationExamples.cs:21: [Serialization: NonSerializableOuterClassWarning] Serializable non-static inner class "SerializationC$Inner" has a non-serializable outer class

since the inner serializable class Inner has SerializationC that is non-serializable outer class. Moreover, field Serialization.f might hold any object, also non-serializable objects, which is not correct for an instance field of a serializable class.