Possibility to explicit remove Serialization support for a lambda

How to handle serializability was one of the biggest challenges for the EG; suffice it to say that there were no great solutions, only tradeoffs between various downsides. Some parties insisted that all lambdas be automatically serializable (!); others insisted that lambdas never be serializable (which seemed an attractive idea at times, but sadly would badly violate user expectations.)

You note:

Well, another solution is to never use lambda expressions/method references in security relevant code,

In fact, the serialization spec now says exactly that.

But, there is a fairly easy trick to do what you want here. Suppose you have some library that wants serializable instances:

public interface SomeLibType extends Runnable, Serializable { }

with methods that expect this type:

public void gimmeLambda(SomeLibType r)

and you want to pass lambdas into it, but not have them be serializable (and take the consequences of that.) So, write yourself this helper method:

public static SomeLibType launder(Runnable r) {
    return new SomeLibType() {
        public void run() { r.run(); }
    }
}

Now you can call the library method:

gimmeLambda(launder(() -> myPrivateMethod()));

The compiler will convert your lambda into a non-serializable Runnable, and the laundering wrapper will wrap it with an instance that satisifies the type system. When you try to serialize it, that will fail since r is not serializable. More importantly, you can’t forge access to the private method, because the $deserializeLambda$ support that’s needed in the capturing class won’t even be there.

Leave a Comment