RFR: 8336492: Regression in lambda serialization [v3]

Liam Miller-Cushon cushon at openjdk.org
Tue Jul 30 17:21:33 UTC 2024


On Tue, 30 Jul 2024 16:25:17 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

> It would be interesting if you could share some details about the deserialization failure: a redundant `this$0` in the serialized stream should be handles (serialization allows to ignore and reorder fields). Was there a name incompatibility in the captures?

I investigated, it looks like the order of a captured local and parameter is now reversed in the signature:


import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Path;

public class X {
  public static void main(String[] args) throws Exception {
    final Path path = Path.of(args[1]);
    switch (args[0]) {
      case "write" -> write(path, "hello");
      case "read" -> read(path);
    }
  }

  static void write(Path path, String s) throws Exception {
    int x = 42;
    Runnable r =
        (Runnable & Serializable)
            () -> {
              System.err.println(s + x);
            };
    try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(path))) {
      oos.writeObject(r);
    }
  }

  static void read(Path path) throws Exception {
    Runnable r;
    try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(path))) {
      r = (Runnable) ois.readObject();
    }
    r.run();
  }
}



$BASELINE/bin/javac --release 22 X.java && $BASELINE/bin/java X write o && $EXPERIMENT/bin/javac --release 22 X.java && $EXPERIMENT/bin/java X read o
...
Exception in thread "main" java.io.InvalidObjectException: ReflectiveOperationException during deserialization
        at java.base/java.lang.invoke.SerializedLambda.readResolve(SerializedLambda.java:280)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at java.base/java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1198)
        at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2278)
        at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1747)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:525)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:483)
        at X.read(X.java:31)
        at X.main(X.java:12)
Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at java.base/java.lang.invoke.SerializedLambda.readResolve(SerializedLambda.java:278)
        ... 9 more
Caused by: java.lang.IllegalArgumentException: Invalid lambda deserialization
        at X.$deserializeLambda$(X.java:7)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        ... 11 more


Comparing the output shows:


494,495c494,495
<   private static void lambda$write$e26d8c1c$1(java.lang.String, int);
<     descriptor: (Ljava/lang/String;I)V
---
>   private static void lambda$write$b96aa0a6$1(int, java.lang.String);
>     descriptor: (ILjava/lang/String;)V

-------------

PR Comment: https://git.openjdk.org/jdk/pull/20349#issuecomment-2258840088


More information about the compiler-dev mailing list