From 95da6ec5a63614b1632cbd3b5db2edd745a9d027 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Mon, 21 Dec 2015 18:37:06 -0800 Subject: [PATCH] `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`. --- interface/src/main/java/xsbti/api/AbstractLazy.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/interface/src/main/java/xsbti/api/AbstractLazy.java b/interface/src/main/java/xsbti/api/AbstractLazy.java index bd21f166f..bd49deded 100644 --- a/interface/src/main/java/xsbti/api/AbstractLazy.java +++ b/interface/src/main/java/xsbti/api/AbstractLazy.java @@ -3,11 +3,17 @@ */ package xsbti.api; - import java.io.ObjectStreamException; +import java.io.ObjectStreamException; public abstract class AbstractLazy implements Lazy, 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(get()); }