Skip to content

Instantly share code, notes, and snippets.

@jerrinot
Created December 28, 2016 16:45
Show Gist options
  • Save jerrinot/3a8e558c14b281d081d5d1a6e7b5f4c3 to your computer and use it in GitHub Desktop.
Save jerrinot/3a8e558c14b281d081d5d1a6e7b5f4c3 to your computer and use it in GitHub Desktop.
package lambdaserialization;
import org.junit.Test;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.function.Function;
import static lambdaserialization.Utils.serializeAndDeserialize;
import static org.junit.Assert.assertEquals;
public class LambdaSerializationTest {
@Test
public void testGeneratedClassEquality_useRegularSerialization() throws Exception {
int capturedDelta = 1;
Function<Integer, Integer> originFunction = (Function<Integer, Integer> & Serializable) i -> i + capturedDelta;
System.out.println(originFunction);
Function<Integer, Integer> deserializedFunction = serializeAndDeserialize(originFunction);
System.out.println(deserializedFunction);
assertEquals(originFunction.getClass(), deserializedFunction.getClass());
}
@Test
public void testGeneratedClassEquality_useHackedMethod() throws Exception {
int delta = 1;
Function<Integer, Integer> originFunction = (Function<Integer, Integer> & Serializable) i -> i + delta;
System.out.println(originFunction);
SerializedLambda serializedLambda = createSerializedLambda(originFunction);
System.out.println(serializedLambda);
Function<Integer, Integer> deserializedFunction = deserializeLambda(serializedLambda);
System.out.println(deserializedFunction);
assertEquals(originFunction.getClass(), deserializedFunction.getClass());
}
@Test
public void testGeneratedClassEquality_mixed() throws Exception {
int delta = 1;
Function<Integer, Integer> originFunction = (Function<Integer, Integer> & Serializable) i -> i + delta;
System.out.println(originFunction);
Function<Integer, Integer> deserializedFunction_regular = serializeAndDeserialize(originFunction);
SerializedLambda serializedLambda = createSerializedLambda(originFunction);
Function<Integer, Integer> deserializedFunction_hacked = deserializeLambda(serializedLambda);
assertEquals(deserializedFunction_regular.getClass(), deserializedFunction_hacked.getClass());
}
private static Function<Integer, Integer> deserializeLambda(SerializedLambda serializedLambda) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Function<Integer, Integer> f;Method deserializeLambdaMethod = LambdaSerializationTest.class.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
deserializeLambdaMethod.setAccessible(true);
f = (Function<Integer, Integer>) deserializeLambdaMethod.invoke(null, serializedLambda);
return f;
}
private static SerializedLambda createSerializedLambda(Object f) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Method writeReplaceMethod = f.getClass().getDeclaredMethod("writeReplace");
writeReplaceMethod.setAccessible(true);
return (SerializedLambda) writeReplaceMethod.invoke(f);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment