Skip to content

Commit

Permalink
Add exception-throwing readObject to classes using the serial-proxy…
Browse files Browse the repository at this point in the history
… pattern.

See _Effective Java_, 3rd edition, Item 90.

RELNOTES=Classes with "serial proxies" acquire exception-throwing `readObject` methods, in accordance with best practice.
PiperOrigin-RevId: 451001736
  • Loading branch information
eamonnmcmanus authored and Google Java Core Libraries committed May 25, 2022
1 parent 76260d9 commit e62d6a0
Show file tree
Hide file tree
Showing 46 changed files with 312 additions and 0 deletions.
9 changes: 9 additions & 0 deletions android/guava/src/com/google/common/cache/LocalCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import com.google.j2objc.annotations.RetainedWith;
import com.google.j2objc.annotations.Weak;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.ref.Reference;
Expand Down Expand Up @@ -4748,6 +4749,10 @@ public void cleanUp() {
Object writeReplace() {
return new ManualSerializationProxy<>(localCache);
}

private void readObject(ObjectInputStream in) throws InvalidObjectException {
throw new InvalidObjectException("Use ManualSerializationProxy");
}
}

static class LocalLoadingCache<K, V> extends LocalManualCache<K, V>
Expand Down Expand Up @@ -4797,5 +4802,9 @@ public final V apply(K key) {
Object writeReplace() {
return new LoadingSerializationProxy<>(localCache);
}

private void readObject(ObjectInputStream in) throws InvalidObjectException {
throw new InvalidObjectException("Use LoadingSerializationProxy");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.NoSuchElementException;
import java.util.Set;
Expand Down Expand Up @@ -162,6 +164,11 @@ Object writeReplace() {
return new SerializedForm<>(domain);
}

@GwtIncompatible // serialization
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}

@GwtIncompatible // NavigableSet
@Override
ImmutableSortedSet<C> createDescendingSet() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import com.google.common.annotations.GwtCompatible;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
Expand Down Expand Up @@ -586,4 +588,8 @@ Builder<K, V> makeBuilder(int size) {
Object writeReplace() {
return new SerializedForm<>(this);
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
import com.google.errorprone.annotations.DoNotMock;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.Arrays;
Expand Down Expand Up @@ -361,6 +363,10 @@ Object writeReplace() {
return new ImmutableList.SerializedForm(toArray());
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}

/**
* Abstract base class for builders of {@link ImmutableCollection} types.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableMap.IteratorBasedImmutableMap;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.EnumMap;
import javax.annotation.CheckForNull;
Expand Down Expand Up @@ -100,6 +102,10 @@ Object writeReplace() {
return new EnumSerializedForm<>(delegate);
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use EnumSerializedForm");
}

/*
* This class is used to serialize ImmutableEnumMap instances.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import com.google.common.annotations.GwtCompatible;
import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.EnumSet;
Expand Down Expand Up @@ -126,6 +128,10 @@ Object writeReplace() {
return new EnumSerializedForm<E>(delegate);
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}

/*
* This class is used to serialize ImmutableEnumSet instances.
*/
Expand Down
6 changes: 6 additions & 0 deletions android/guava/src/com/google/common/collect/ImmutableMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.RetainedWith;
import com.google.j2objc.annotations.WeakOuter;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.Arrays;
Expand Down Expand Up @@ -1128,4 +1130,8 @@ Builder<K, V> makeBuilder(int size) {
Object writeReplace() {
return new SerializedForm<>(this);
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Map.Entry;
import javax.annotation.CheckForNull;
Expand Down Expand Up @@ -108,6 +110,11 @@ Object writeReplace() {
return new EntrySetSerializedForm<>(map());
}

@GwtIncompatible // serialization
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use EntrySetSerializedForm");
}

@GwtIncompatible // serialization
private static class EntrySetSerializedForm<K, V> implements Serializable {
final ImmutableMap<K, V> map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import com.google.errorprone.annotations.DoNotMock;
import com.google.j2objc.annotations.Weak;
import com.google.j2objc.annotations.WeakOuter;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -662,6 +664,11 @@ boolean isPartialView() {
Object writeReplace() {
return new KeysSerializedForm(ImmutableMultimap.this);
}

@GwtIncompatible
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use KeysSerializedForm");
}
}

@GwtIncompatible
Expand Down
12 changes: 12 additions & 0 deletions android/guava/src/com/google/common/collect/ImmutableMultiset.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.google.errorprone.annotations.DoNotCall;
import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.WeakOuter;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -365,6 +367,11 @@ Object writeReplace() {
return new EntrySetSerializedForm<E>(ImmutableMultiset.this);
}

@GwtIncompatible
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use EntrySetSerializedForm");
}

private static final long serialVersionUID = 0;
}

Expand All @@ -385,6 +392,11 @@ Object readResolve() {
@Override
abstract Object writeReplace();

@GwtIncompatible
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}

/**
* Returns a new builder. The generated builder is equivalent to the builder created by the {@link
* Builder} constructor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
import com.google.errorprone.annotations.DoNotMock;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -406,5 +408,9 @@ Object writeReplace() {
return new SerializedForm<>(asMapOfRanges());
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}

private static final long serialVersionUID = 0;
}
10 changes: 10 additions & 0 deletions android/guava/src/com/google/common/collect/ImmutableRangeSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.Iterator;
Expand Down Expand Up @@ -680,6 +682,10 @@ public String toString() {
Object writeReplace() {
return new AsSetSerializedForm<C>(ranges, domain);
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}
}

private static class AsSetSerializedForm<C extends Comparable> implements Serializable {
Expand Down Expand Up @@ -829,4 +835,8 @@ Object readResolve() {
Object writeReplace() {
return new SerializedForm<C>(ranges);
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}
}
6 changes: 6 additions & 0 deletions android/guava/src/com/google/common/collect/ImmutableSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.concurrent.LazyInit;
import com.google.j2objc.annotations.RetainedWith;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -384,6 +386,10 @@ Object writeReplace() {
return new SerializedForm(toArray());
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}

/**
* Returns a new builder. The generated builder is equivalent to the builder created by the {@link
* Builder} constructor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import com.google.common.annotations.GwtCompatible;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Comparator;
Expand Down Expand Up @@ -1139,6 +1141,10 @@ Object writeReplace() {
return new SerializedForm<>(this);
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}

// This class is never actually serialized directly, but we have to make the
// warning go away (and suppressing would suppress for all nested classes too)
private static final long serialVersionUID = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
import com.google.errorprone.annotations.concurrent.LazyInit;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -671,4 +673,8 @@ Object readResolve() {
Object writeReplace() {
return new SerializedForm<E>(this);
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.MoreObjects;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.DoNotCall;
import com.google.errorprone.annotations.DoNotMock;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Iterator;
Expand Down Expand Up @@ -453,4 +456,9 @@ Object readResolve() {
final Object writeReplace() {
return createSerializedForm();
}

@GwtIncompatible // serialization
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.google.j2objc.annotations.Weak;
import com.google.j2objc.annotations.WeakOuter;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
Expand Down Expand Up @@ -2845,6 +2846,10 @@ Object writeReplace() {
this);
}

private void readObject(ObjectInputStream in) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializationProxy");
}

/**
* The actual object that gets serialized. Unfortunately, readResolve() doesn't get called when a
* circular dependency is present, so the proxy must be able to behave as the map itself.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import com.google.common.annotations.GwtIncompatible;
import com.google.common.primitives.Primitives;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
Expand Down Expand Up @@ -172,6 +174,10 @@ private Object writeReplace() {
return new SerializedForm(delegate());
}

private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use SerializedForm");
}

/** Serialized form of the map, to avoid serializing the constraint. */
private static final class SerializedForm<B> implements Serializable {
private final Map<Class<? extends B>, B> backingMap;
Expand Down
Loading

0 comments on commit e62d6a0

Please sign in to comment.