A DESCRIPTION OF THE PROBLEM :
Deserializing a method reference might use the wrong signature if there are more than one method reference to the same method in the same class.
This is probably a side effect of JDK-8202922.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use two (or more) serializable method references in the same class, where signature of the first method reference is more restrictive than the second.
Serialize & deserialize the second method reference.
Call the deserialized method reference with something that is not legal for the first method reference.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The deserialized method reference works as advertised.
ACTUAL -
A ClassCastException is thrown
Exception in thread "main" java.lang.ClassCastException: java.base/java.lang.Object cannot be cast to java.base/java.lang.String
at SerialLambdaBug.main(SerialLambdaBug.java:19)
---------- BEGIN SOURCE ----------
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.util.function.Function;
public class SerialLambdaBug {
public static void main(String[] args) throws Exception {
// If you comment out the next line, this test will not throw an exception.
Function<String,String> lambda1 = (Function<String,String> & Serializable) Object::toString;
Function<Object,String> lambda2 = (Function<Object,String> & Serializable) Object::toString;
Function<Object,String> deserial = serialDeserial(lambda2);
// This throws a class clast exception
deserial.apply(new Object());
}
@SuppressWarnings("unchecked")
static <T> T serialDeserial(T object) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
T result = (T) ois.readObject();
ois.close();
return result;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Don't use method references, use a lambda expression instead
FREQUENCY : always