`AbstractLazy`'s `writeObject` is `protected`

Fix for regression triggered by #2325 -- apparently, the API visitor would
force all the lazy stubs so the `AbstractLazy` `writeReplace` was not exercised.
With the private subtrees being ignored, the visitor didn't force the lazy stub,
and the `writeProtected` method was not inherited in `SafeLazy.Impl`.

From https://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
`writeReplace` must be protected for its override to be inherited.

> `Serializable` classes that need to designate an alternative object to be used
> when writing an object to the stream should implement this special method with
> the exact signature:
> `ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;`
>
> This `writeReplace` method is invoked by serialization if the method exists and
> it would be accessible from a method defined within the class of the object
> being serialized. Thus, the method can have `private`, `protected` and
> `package-private` access.
>
> **Subclass access to this method follows java accessibility rules.**

(Thanks to retronym for digging up the docs.)

The fix is captured, indirectly, by the scripted test
`source-dependencies/java-analysis-serialization-error`.
This commit is contained in:
Adriaan Moors 2015-12-21 18:37:06 -08:00
parent 9a856be5ca
commit 95da6ec5a6
1 changed files with 8 additions and 2 deletions

View File

@ -3,11 +3,17 @@
*/
package xsbti.api;
import java.io.ObjectStreamException;
import java.io.ObjectStreamException;
public abstract class AbstractLazy<T> implements Lazy<T>, java.io.Serializable
{
private Object writeReplace() throws ObjectStreamException
// `writeReplace` must be `protected`, so that the `Impl` subclass
// inherits the serialization override.
//
// (See source-dependencies/java-analysis-serialization-error, which would
// crash trying to serialize an AbstractLazy, because it pulled in an
// unserializable type eventually.)
protected Object writeReplace() throws ObjectStreamException
{
return new StrictLazy<T>(get());
}