JDK-8027681 : Lambda serialization fails once reflection proxy generation kicks in
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 8
  • Priority: P1
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2013-10-31
  • Updated: 2013-11-22
  • Resolved: 2013-11-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 Other
8 b117Fixed port-stage-ppc-aixFixed
Related Reports
Duplicate :  
Duplicate :  
Description
 Now that lambda proxies are anonymous, when we cross the threshold where reflection proxies are generated to invoke writeReplace, linkage of the reflection proxy fails with CFNE, causing serialization to fail:

LambdaObject: org.openjdk.tests.java.util.stream.IntReduceTest$$Lambda$1004/961982062@69dd3352 [ 20 ]
   [testng]     Throwable: java.lang.NoClassDefFoundError: org/openjdk/tests/java/util/stream/IntReduceTest$$Lambda$1004/961982062java.lang.NoClassDefFoundError: org/openjdk/tests/java/util/stream/IntReduceTest$$Lambda$1004/961982062
   [testng] 	at sun.reflect.GeneratedMethodAccessor273.invoke(Unknown Source)
   [testng] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   [testng] 	at java.lang.reflect.Method.invoke(Method.java:483)
   [testng] 	at java.io.ObjectStreamClass.invokeWriteReplace(ObjectStreamClass.java:1075)
   [testng] 	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1136)
   [testng] 	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
   [testng] 	at com.oracle.lambda.TestLambdaSerialization.serializeAndDeserialize0(TestLambdaSerialization.java:128)

Test patch to detect failures:

diff -r f6bc96afc5d4 test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
--- a/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
+++ b/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
@@ -45,15 +45,19 @@
  */
 @Test
 public class SerializedLambdaTest {
+    public static final int REPS = 50;
+
     @SuppressWarnings("unchecked")
     private<T> void assertSerial(T p, Consumer<T> asserter) throws IOException, ClassNotFoundException {
         asserter.accept(p);
 
-        byte[] bytes = serialize(p);
+        for (int i=0; i<REPS; i++) {
+            byte[] bytes = new byte[0];
+            bytes = serialize(p);
         assertTrue(bytes.length > 0);
-
         asserter.accept((T) deserialize(bytes));
     }
+    }
 
     private void assertNotSerial(Predicate<String> p, Consumer<Predicate<String>> asserter)



Comments
Verified by the regression tests provided with this fix.
22-11-2013

RULE api/java_lang/invoke/SerializedLambda/serial/LambdaSerializationTests_LambdaSerializationTests any any
12-11-2013

Here is a very simple stand-alone test -- import java.io.*; public class LambdaSerialization { public static void main(String[] args) throws Exception { LSI ls = z -> "[" + z + "]"; for (int i = 0; i < 20; ++i) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutput out = new ObjectOutputStream(baos); out.writeObject(ls); out.flush(); out.close(); } } } interface LSI extends Serializable { String convert(String x); }
01-11-2013

8-critical-sqe: this should be fixed, serialization fails in a common scenario.
01-11-2013

This is a known issue.
31-10-2013

Possible fix currently under review.
31-10-2013