Stability of lambda serialization
Sam Pullara
sam at sampullara.com
Sat Jul 27 09:52:25 PDT 2013
I think the requirement should be that you have the same classes on each
side of the wire.
Sam
On Tue, Jul 23, 2013 at 10:35 AM, Scott Stark <sstark at redhat.com> wrote:
> Red Hat has a concern regarding how fragile the default serialization
> behavior of lambda expressions is in the current reference implementation,
> currently:
> ironmaiden:OpenJDK starksm$
> /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/java
> -version
> java version "1.8.0-ea"
> Java(TM) SE Runtime Environment (build 1.8.0-ea-b98)
> Java HotSpot(TM) 64-Bit Server VM (build 25.0-b40, mixed mode)
>
> The problem is that the serialized form of a lambda expression depends on
> the order in which captured arguments are declared. The attached simple
> example demonstrates how easy it is for a trivial reordering of the lambda
> code block to result in an inability to deserialize a previously saved
> expression.
>
> To produce this exception:
> 1. Run the serialization.AuthenticationContext.testWriteLambda method with
> the lambda expression written as:
> Authenticator a = (Authenticator & Serializable) (String principal,
> char[] pass) -> {
> // Run with p declared first when writing out the
> /tmp/testWriteLambda.bin, then switch
> // to declare u first when running testReadLambda
> String p = "-> Password " + password + " <-";
> String u = "-> User " + user + " <-";
> return u + " " + p;
> };
> 2. Change the lambda expression to:
> Authenticator a = (Authenticator & Serializable) (String principal,
> char[] pass) -> {
> // Run with p declared first when writing out the
> /tmp/testWriteLambda.bin, then switch
> // to declare u first when running testReadLambda
> String u = "-> User " + user + " <-";
> String p = "-> Password " + password + " <-";
> return u + " " + p;
> };
>
> Recompile and run serialization.AuthenticationContext.testReadLambda to
> produce:
>
> java.io.IOException: unexpected exception type
> at
> java.io.ObjectStreamClass.throwMiscException(ObjectStreamClass.java:1538)
> at
> java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1110)
> at
> java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1807)
> at
> java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
> at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
> at
> serialization.AuthenticationContext.testReadLambda(AuthenticationContext.java:34)
> ...
> Caused by: java.lang.reflect.InvocationTargetException
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at
> java.lang.invoke.SerializedLambda.readResolve(SerializedLambda.java:222)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at
> java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1104)
> ... 30 more
> Caused by: java.lang.IllegalArgumentException: Invalid lambda
> deserialization
> at
> serialization.AuthenticationContext.$deserializeLambda$(AuthenticationContext.java:1)
> ... 40 more
>
> One does not see the same level of sensitivity to the ordering of the
> serialization fields in a POJO as demonstrated by the
> serialization.AuthenticationContext.testWritePOJO/testReadPOJO cases where
> one can reorder the TestPOJO.{user,password} fields without having
> serialization fail.
>
> We would like to see at least that level of stability of the serialized
> form of lambda expressions.
>
More information about the lambda-spec-observers
mailing list