78 lines
2.5 KiB
Plaintext
78 lines
2.5 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Java offers a built-in serialization mechanism for classes that implement the `Serializable` interface.
|
|
The developer can either rely on Java's default serialization and deserialization logic or implement custom methods for these tasks.
|
|
The JVM will use methods such as `readObject` and `writeObject` to execute custom behavior.
|
|
This only works, however, if these methods match exactly the expected signatures.
|
|
If they do not, the JVM will fall back to the default logic, resulting in unexpected behavior at runtime,
|
|
while the developer believes that the default logic has been overidden.
|
|
|
|
|
|
This rule raises an issue if an implementation of `writeObject`, `readObject`, `readObjectNoData`, `writeReplace`, or `readResolve`
|
|
has an incorrect access modifier, return type, or is not static when it should be (and vice-versa).
|
|
|
|
|
|
== How to fix it
|
|
|
|
Ensure that the serialization-related method's signatures match exactly those required by the JVM.
|
|
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
public class Watermelon implements Serializable {
|
|
|
|
void writeObject(java.io.ObjectOutputStream out) // Noncompliant, "writeObject" needs to be private, which it is not here
|
|
throws IOException
|
|
{...}
|
|
|
|
static Object readResolve() throws ObjectStreamException // Noncompliant, "readResolve" should not be static
|
|
{...}
|
|
|
|
Watermelon writeReplace() throws ObjectStreamException // Noncompliant, "writeReplace" must return "java.lang.Object"
|
|
{...}
|
|
}
|
|
----
|
|
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
public class Watermelon implements Serializable {
|
|
|
|
private void writeObject(java.io.ObjectOutputStream out) // Compliant, method declared as private
|
|
throws IOException
|
|
{...}
|
|
|
|
protected Object readResolve() throws ObjectStreamException // Compliant, method is not static
|
|
{...}
|
|
|
|
private Object writeReplace() throws ObjectStreamException // Compliant, method returns "java.lang.Object"
|
|
{...}
|
|
}
|
|
----
|
|
|
|
|
|
== Resources
|
|
|
|
* https://wiki.sei.cmu.edu/confluence/x/WTdGBQ[CERT, SER01-J.] - Do not deviate from the proper signatures of serialization methods
|
|
* https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Serializable.html[Oracle SDK - java.io.Serializable]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
* Make "xxx" "private".
|
|
* The "zzz" modifier should not be applied to "xxx".
|
|
|
|
|
|
endif::env-github,rspecator-view[]
|