CodeQL documentation

ReadResolve must have Object return type, not void

ID: java/wrong-readresolve-signature
Kind: problem
Security severity: 
Severity: warning
Precision: medium
Tags:
   - reliability
   - maintainability
   - language-features
Query suites:
   - java-security-and-quality.qls

Click to see the query in the CodeQL repository

If a class uses the readResolve method to specify a replacement object instance when the object is read from a stream, ensure that the signature of readResolve is exactly what the Java serialization mechanism expects.

Recommendation

Ensure that the signature of the readResolve method in the class matches the expected signature:

ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;

Note that the method must return a java.lang.Object.

If readResolve is used for instance control of a serializable singleton, (that is, to make sure that deserializing a singleton class does not result in another instance of the singleton) it may be possible to use an enum with a single element instead. The Java serialization specification explicitly ensures that deserializing an enum does not create a new instance. (For details about this technique, see [Bloch].)

Example

In the following example, FalseSingleton.readResolve has the wrong signature, which causes deserialization to create a new instance of the singleton. However, Singleton.readResolve has the correct signature, which means that deserialization does not result in another instance of the singleton.

class FalseSingleton implements Serializable {
	private static final long serialVersionUID = -7480651116825504381L;
	private static FalseSingleton instance;
	
	private FalseSingleton() {}
	
	public static FalseSingleton getInstance() {
		if (instance == null) {
			instance = new FalseSingleton();
		}
		return instance;
	}
	
	// BAD: Signature of 'readResolve' does not match the exact signature that is expected
	// (that is, it does not return 'java.lang.Object').
	public FalseSingleton readResolve() throws ObjectStreamException {
		return FalseSingleton.getInstance();
	}
}

class Singleton implements Serializable {
	private static final long serialVersionUID = -7480651116825504381L;
	private static Singleton instance;
	
	private Singleton() {}
	
	public static Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
	
	// GOOD: Signature of 'readResolve' matches the exact signature that is expected.
	// It replaces the singleton that is read from a stream with an instance of 'Singleton',
	// instead of creating a new singleton.
	private Object readResolve() throws ObjectStreamException {
		return Singleton.getInstance();
	}
}

References

  • © GitHub, Inc.
  • Terms
  • Privacy
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy