Stability of lambda serialization

Scott Stark sstark at redhat.com
Mon Aug 5 11:09:14 PDT 2013


So Red Hat will go on the record to state that if serialization of lambdas is beyond the scope that DML suggested, we will vote no on the JSR. As a concluding remark on issue, consider an alternate form of the example given where the user and password variable types do not differ. In this situation, the reordering results in the password seen as the user. I can see that this will be the subject of yet another CVE somewhere down the road.


Running testReadLambda after reorder...
-> User secret1password <- -> Password bob <-



----- Original Message -----
From: "Paul Benedict" <pbenedict at apache.org>
To: lambda-spec-observers at openjdk.java.net
Cc: "Scott Stark" <sstark at redhat.com>, lambda-spec-experts at openjdk.java.net
Sent: Saturday, August 3, 2013 4:54:58 PM
Subject: Re: Stability of lambda serialization

I imagine this will mostly impact EE applications in a very negative way.
It's one thing if my method signatures change, or I explicitly add some
fields, but now adding/removing a local lambda will do that? Serialization
errors are the worst thing in EE -- and this kind of just heaps on more
misery.

Paul


On Sat, Aug 3, 2013 at 2:00 AM, Brian Goetz <brian.goetz at oracle.com> wrote:

> This was discussed in the meeting after JVMLS this week.  The consensus
> was that, while *this particular* issue could be addressed, there is an
> infinite spectrum of similar issues that cannot be addressed, and that it
> is preferable to draw a clean line about what the user can expect in terms
> of code changes destabilizing lambdas.
>
> That line is: If the code inside a method, or the method's signature,
> changes *in any way*, lambdas captured in that method should be considered
> destabilized.  Changes to other methods, or changes to the order of
> methods, do not affect lambdas in an unchanged method.
>
> On Jul 23, 2013, at 10:35 AM, Scott Stark 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.
> > <AuthenticationContext.java><TestPOJO.java><Authenticator.java>
>
>


-- 
Cheers,
Paul


More information about the lambda-spec-observers mailing list