Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8208752

Calling a deserialized Lambda might fail with ClassCastException

XMLWordPrintable

      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


            smarks Stuart Marks
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: