-
Sub-task
-
Resolution: Fixed
-
P4
-
None
-
None
Create a tool, ideally which can be run as a java.lang.instrument agent, to enable running of lambda tests in an alternate mode where all lambdas are made serializable and their serializability verified, and tests performed using a deserialized copy.
A sketch of the idea is below.
The lambda capture site for
a non-serializable lambda looks different from a serializable one. A
regular capture site looks like:
indy:
bootstrap = java.lang.invoke.LambdaMetafactory.metaFactory
static args =
MethodHandle[ functional interface method ]
MethodHandle[ impl method ]
MethodType[ instantiated method type ]
dyn args = captured lambda args
Think of this as the "simplified" or "fast path" metafactory. A serializable capture looks like:
indy:
bootstrap = java.lang.invoke.LambdaMetafactory.altMetaFactory
static args =
MethodHandle[ functional interface method ]
MethodHandle[ impl method ]
MethodType[ instantiated method type ]
flags word with SERIALIZABLE bit set
zero or more marker interfaces result should implement
dyn args = captured lambda args
So, the approach is this: take our existing tests, grovel over the bytecode
using ASM, find the regular capture sites, and replace them with a
serializable capture site and a call to a method like:
newLambdaObject = checkSerialization(lambdaObject, captured args...)
The implementation of this method would check to see whether all
captured args are serializable, if so, would serialize and deserialize
the object and return that, otherwise just return the input object.
Then we use the above to mangle the bytecode of our existing lambda
tests, and run both the regular and mangled versions. The idea being
that all our existing lambda tests now are run in both nonserializable
and serializable modes, increasing test coverage of serialization
handling.
A sketch of the idea is below.
The lambda capture site for
a non-serializable lambda looks different from a serializable one. A
regular capture site looks like:
indy:
bootstrap = java.lang.invoke.LambdaMetafactory.metaFactory
static args =
MethodHandle[ functional interface method ]
MethodHandle[ impl method ]
MethodType[ instantiated method type ]
dyn args = captured lambda args
Think of this as the "simplified" or "fast path" metafactory. A serializable capture looks like:
indy:
bootstrap = java.lang.invoke.LambdaMetafactory.altMetaFactory
static args =
MethodHandle[ functional interface method ]
MethodHandle[ impl method ]
MethodType[ instantiated method type ]
flags word with SERIALIZABLE bit set
zero or more marker interfaces result should implement
dyn args = captured lambda args
So, the approach is this: take our existing tests, grovel over the bytecode
using ASM, find the regular capture sites, and replace them with a
serializable capture site and a call to a method like:
newLambdaObject = checkSerialization(lambdaObject, captured args...)
The implementation of this method would check to see whether all
captured args are serializable, if so, would serialize and deserialize
the object and return that, otherwise just return the input object.
Then we use the above to mangle the bytecode of our existing lambda
tests, and run both the regular and mangled versions. The idea being
that all our existing lambda tests now are run in both nonserializable
and serializable modes, increasing test coverage of serialization
handling.
- is blocked by
-
JDK-8005653 Lambdas containing inner classes referencing external type variables do not correctly parameterize the inner class
- Closed
- is cloned by
-
JDK-8006644 Bridge testing framework
- Resolved