"An inner class is a nested class that is not explicitly or implicitly declared {{ static}}" \ [[JLS 2005|AA. Bibliography#JLS 05]\JLS 2015]. Serialization of inner classes (including local and anonymous classes) is error prone. According to the Serialization Specification \[ [Sun 2006|AA. Bibliography#Sun 06]\]Wiki Markup
...
]:
- Serializing an inner class declared in a non-static context that contains implicit non-transient references to enclosing class instances
...
- results in serialization of its associated outer class instance.
- Synthetic fields generated by
...
- Java
...
- compilers
...
- to implement inner classes are implementation dependent and may vary between compilers; differences in such fields can disrupt compatibility as well as result in conflicting default
serialVersionUIDvalues. The names assigned to local and anonymous inner classes are also implementation dependent and may differ between compilers.
- Because inner classes cannot declare static members other than compile-time constant fields, they cannot use the
serialPersistentFieldsmechanism to designate serializable fields.
...
- Because inner classes associated with outer instances do not have zero-argument constructors (constructors of such inner classes implicitly accept the enclosing instance as a prepended parameter), they cannot implement
Externalizable. TheExternalizableinterface requires the implementing object to manually save and restore its state using thewriteExternal()andreadExternal()methods.
Consequently, programs are forbidden to must not serialize inner classes.
Note, however, that Because none of the above these issues apply to static member classes. Consequently, serialization of static member classes is permitted.
...
In this noncompliant code example, the fields contained within the outer class are also serialized when the inner class is serialized. :
| Code Block | ||
|---|---|---|
| ||
public class OuterSer implements Serializable { private int rank; class InnerSer implements Serializable { protected String name; // ... } } |
Compliant Solution
This The InnerSer class of this compliant solution omits implementation of deliberately fails to implement the Serializable interface in the InnerSer class.:
| Code Block | ||
|---|---|---|
| ||
public class OuterSer implements Serializable { private int rank; class InnerSer { protected String name; // ... } } |
Compliant Solution
It is allowable to declare If an inner and outer class must both be Serializable, the inner class as can be declared static to prevent its serialization. It is also permissible for a static inner class to implement Serializablea serialized inner class from also serializing its outer class.
| Code Block | ||
|---|---|---|
| ||
public class OuterSer implements Serializable { private int rank; static class InnerSer implements Serializable { protected String name; // ... } } |
Risk Assessment
Attempts to serialize Serialization of inner classes can introduce platform dependencies and can cause serialization of instances of the outer class.
Rule | Severity | Likelihood |
|---|
Detectable | Repairable | Priority | Level |
|---|---|---|---|
SER05-J | Medium |
Likely |
Yes |
No |
P12 | L1 |
Automated Detection
Detection of inner classes that implement serialization appears to be is straightforward.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="60d210f2-2d46-41ef-a09d-6b684001709f"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. Bibliography#API 06]] |
| ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="3c532d7c-a939-4449-835c-c28c3ecf9321"><ac:plain-text-body><![CDATA[ | [[Bloch 2008 | AA. Bibliography#Bloch 08]] | Item 74: "Implement serialization judiciously" | ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0e1e770d-1204-4925-9dd4-74b418162e5f"><ac:plain-text-body><![CDATA[ | [[JLS 2005 | AA. Bibliography#JLS 05]] | [Section 8.1.3, Inner Classes and Enclosing Instances | http://java.sun.com/docs/books/jls/third_edition/html/classes.html] | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="d34847d1-2c78-488f-9278-debd1c1e523c"><ac:plain-text-body><![CDATA[ | [[Sun 2006 | AA. Bibliography#Sun 06]] | "Serialization specification" | ]]></ac:plain-text-body></ac:structured-macro> |
| Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Klocwork |
| JAVA.SERIALIZE.INNER | |||||||
| SonarQube |
| S2066 S2059 | "Serializable" inner classes of non-serializable classes should be "static" "Serializable" inner classes of "Serializable" classes should be static |
Related Guidelines
Bibliography
[API 2014] | |
Item 74, "Implement Serialization Judiciously" | |
[JLS 2015] | |
[Sun 2006] | Serialization Specification, Section 1.10, "The Serializable Interface" |
...