1923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller/*
2923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * Copyright (C) 2016 The Android Open Source Project
3923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller *
4923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * Licensed under the Apache License, Version 2.0 (the "License");
5923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * you may not use this file except in compliance with the License.
6923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * You may obtain a copy of the License at
7923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller *
8923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller *      http://www.apache.org/licenses/LICENSE-2.0
9923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller *
10923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * Unless required by applicable law or agreed to in writing, software
11923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * distributed under the License is distributed on an "AS IS" BASIS,
12923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * See the License for the specific language governing permissions and
14923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller * limitations under the License.
15923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller */
16923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
17923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerpackage libcore.java.lang;
18923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
19923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport junit.framework.TestCase;
20923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
21923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.io.ByteArrayInputStream;
22923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.io.ByteArrayOutputStream;
23923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.io.IOException;
24923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.io.NotSerializableException;
25923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.io.ObjectInputStream;
26923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.io.ObjectOutputStream;
27923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.io.Serializable;
28923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.lang.reflect.Method;
29923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.lang.reflect.Modifier;
30ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fullerimport java.util.ArrayList;
31923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.util.Arrays;
32923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.util.HashSet;
33923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.util.List;
34923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.util.Set;
35923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerimport java.util.concurrent.Callable;
36923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
37923866595bd9ed27eff087d61843299f387ff5d9Neil Fullerpublic class LambdaImplementationTest extends TestCase {
38923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
39ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller    private static final String STATIC_METHOD_RESPONSE = "StaticMethodResponse";
40923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
41923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testNonCapturingLambda() throws Exception {
42ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        Callable<String> r1 = () -> "Hello World";
43923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(r1);
44923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class);
45923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(r1, Callable.class);
46923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNonSerializableLambdaCharacteristics(r1);
47ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertCallableBehavior(r1, "Hello World");
48923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
49ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        List<Callable<String>> callables = new ArrayList<>();
50ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        for (int i = 0; i < 2; i++) {
51ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            callables.add(() -> "Hello World");
52ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        }
53ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleDefinitionCharacteristics(r1, callables.get(0));
54ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
55923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
56923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
57923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    interface Condition<T> {
58923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        boolean check(T arg);
59923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
60923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
61923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testInstanceMethodReferenceLambda() throws Exception {
62923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Condition<String> c = String::isEmpty;
63923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Class<?> lambdaClass = c.getClass();
64923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(c);
65923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(c, Condition.class);
66923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(c, Condition.class);
67923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNonSerializableLambdaCharacteristics(c);
68923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
69923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Check the behavior of the lambda's method.
70923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertTrue(c.check(""));
71923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(c.check("notEmpty"));
72923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
73923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Method implCallMethod = lambdaClass.getMethod(
74923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                "check", Object.class /* type erasure => not String.class */);
75923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertTrue((Boolean) implCallMethod.invoke(c, ""));
76923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse((Boolean) implCallMethod.invoke(c, "notEmpty"));
77923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
78923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Method interfaceCallMethod = Condition.class.getDeclaredMethod(
79923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                "check", Object.class /* type erasure => not String.class */);
80923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertTrue((Boolean) interfaceCallMethod.invoke(c, ""));
81923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse((Boolean) interfaceCallMethod.invoke(c, "notEmpty"));
82923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
83923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
84923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testStaticMethodReferenceLambda() throws Exception {
85923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Callable<String> r1 = LambdaImplementationTest::staticMethod;
86923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(r1);
87923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class);
88923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(r1, Callable.class);
89923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNonSerializableLambdaCharacteristics(r1);
90923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
91ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertCallableBehavior(r1, STATIC_METHOD_RESPONSE);
92923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
93ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        List<Callable<String>> callables = new ArrayList<>();
94ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        for (int i = 0; i < 2; i++) {
95ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            callables.add(LambdaImplementationTest::staticMethod);
96ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        }
97ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleDefinitionCharacteristics(r1, callables.get(0));
98ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
99923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
100923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
101923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testObjectMethodReferenceLambda() throws Exception {
102ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        String msg = "Hello";
103ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        StringBuilder o = new StringBuilder(msg);
104923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Callable<String> r1 = o::toString;
105923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(r1);
106923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class);
107923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(r1, Callable.class);
108923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNonSerializableLambdaCharacteristics(r1);
109923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
110ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertCallableBehavior(r1, msg);
111923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
112ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        List<Callable<String>> callables = new ArrayList<>();
113ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        for (int i = 0; i < 2; i++) {
114ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            callables.add(o::toString);
115ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        }
116ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleDefinitionCharacteristics(r1, callables.get(0));
117ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
118923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
119923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
120923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testArgumentCapturingLambda() throws Exception {
121ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        checkArgumentCapturingLambda("Argument");
122ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller    }
123ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller
124ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller    private void checkArgumentCapturingLambda(String msg) throws Exception {
125923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Callable<String> r1 = () -> msg;
126923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(r1);
127923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class);
128923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(r1, Callable.class);
129923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNonSerializableLambdaCharacteristics(r1);
130923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
131ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertCallableBehavior(r1, msg);
132923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
133ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        List<Callable<String>> callables = new ArrayList<>();
134ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        for (int i = 0; i < 2; i++) {
135ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            callables.add(() -> msg);
136ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        }
137ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleDefinitionCharacteristics(r1, callables.get(0));
138ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
139923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
140923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
141923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testSerializableLambda_withoutState() throws Exception {
142ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        Callable<String> r1 = (Callable<String> & Serializable) () -> "No State";
143923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(r1);
144923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class, Serializable.class);
145923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(r1, Callable.class);
146923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertSerializableLambdaCharacteristics(r1);
147923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
148ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertCallableBehavior(r1, "No State");
149923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
150ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        List<Callable<String>> callables = new ArrayList<>();
151ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        for (int i = 0; i < 2; i++) {
152ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            Callable<String> callable = (Callable<String> & Serializable) () -> "No State";
153ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            assertLambdaImplementsInterfaces(callable, Callable.class, Serializable.class);
154ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            callables.add(callable);
155ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        }
156ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleDefinitionCharacteristics(r1, callables.get(0));
157ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
158923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
159923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
160923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testSerializableLambda_withState() throws Exception {
161ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        final long state = System.currentTimeMillis();
162ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        Callable<String> r1 = (Callable<String> & Serializable) () -> "State:" + state;
163923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(r1);
164923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class, Serializable.class);
165923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(r1, Callable.class);
166923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertSerializableLambdaCharacteristics(r1);
167923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
168ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertCallableBehavior(r1, "State:" + state);
169923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
170923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Callable<String> deserializedR1 = roundtripSerialization(r1);
171923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(r1.call(), deserializedR1.call());
172ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller
173ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        List<Callable<String>> callables = new ArrayList<>();
174ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        for (int i = 0; i < 2; i++) {
175ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            Callable<String> callable = (Callable<String> & Serializable) () -> "State:" + state;
176ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            assertLambdaImplementsInterfaces(callable, Callable.class, Serializable.class);
177ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            callables.add(callable);
178ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        }
179ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleDefinitionCharacteristics(r1, callables.get(0));
180ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
181923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
182923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
183923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testBadSerializableLambda() throws Exception {
184923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        final Object state = new Object(); // Not Serializable
185923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Callable<String> r1 = (Callable<String> & Serializable) () -> "Hello world: " + state;
186923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(r1);
187923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(r1, Callable.class);
188923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class, Serializable.class);
189923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
190923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        try {
191923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            serializeObject(r1);
192923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            fail();
193923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        } catch (NotSerializableException expected) {
194923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        }
195923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
196923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
197923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    public void testMultipleInterfaceLambda() throws Exception {
198ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        Callable<String> r1 = (Callable<String> & MarkerInterface) () -> "MultipleInterfaces";
199923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertTrue(r1 instanceof MarkerInterface);
200923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertGeneralLambdaClassCharacteristics(r1);
201923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaMethodCharacteristics(r1, Callable.class);
202923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class, MarkerInterface.class);
203923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNonSerializableLambdaCharacteristics(r1);
204923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
205ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertCallableBehavior(r1, "MultipleInterfaces");
206ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller
207ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        List<Callable<String>> callables = new ArrayList<>();
208ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        for (int i = 0; i < 2; i++) {
209ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            Callable<String> callable =
210ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller                    (Callable<String> & MarkerInterface) () -> "MultipleInterfaces";
211ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            assertLambdaImplementsInterfaces(callable, Callable.class, MarkerInterface.class);
212ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            callables.add(callable);
213ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        }
214ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertLambdaImplementsInterfaces(r1, Callable.class, MarkerInterface.class);
215ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleDefinitionCharacteristics(r1, callables.get(0));
216ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertMultipleInstanceCharacteristics(callables.get(0), callables.get(1));
217923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
218923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
219923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static void assertSerializableLambdaCharacteristics(Object r1) throws Exception {
220923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertTrue(r1 instanceof Serializable);
221923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
222923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Object deserializedR1 = roundtripSerialization(r1);
223923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(deserializedR1.equals(r1));
224923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNotSame(deserializedR1, r1);
225923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
226923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
227923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    @SuppressWarnings("unchecked")
228923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static <T> T roundtripSerialization(T r1) throws Exception {
229923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        byte[] bytes = serializeObject(r1);
230923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
231923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        try (ObjectInputStream is = new ObjectInputStream(bais)) {
232923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            return (T) is.readObject();
233923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        }
234923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
235923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
236923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static <T> byte[] serializeObject(T r1) throws IOException {
237923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        ByteArrayOutputStream baos = new ByteArrayOutputStream();
238923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        try (ObjectOutputStream os = new ObjectOutputStream(baos)) {
239923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            os.writeObject(r1);
240923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            os.flush();
241923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        }
242923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        return baos.toByteArray();
243923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
244923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
245923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static <T> void assertLambdaImplementsInterfaces(T r1, Class<?>... expectedInterfaces)
246923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            throws Exception {
247923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Class<?> lambdaClass = r1.getClass();
248923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
249923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Check directly implemented interfaces. Ordering is well-defined.
250923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Class<?>[] actualInterfaces = lambdaClass.getInterfaces();
251923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(expectedInterfaces.length, actualInterfaces.length);
252923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        List<Class<?>> actual = Arrays.asList(actualInterfaces);
253923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        List<Class<?>> expected = Arrays.asList(expectedInterfaces);
254923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(expected, actual);
255923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
256923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Confirm that the only method declared on the lambda's class are those defined by
257923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // interfaces it implements. i.e. there's no additional public contract.
258923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Set<Method> declaredMethods = new HashSet<>();
259923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        addNonStaticPublicMethods(lambdaClass, declaredMethods);
260923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Set<Method> expectedMethods = new HashSet<>();
261923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        for (Class<?> interfaceClass : expectedInterfaces) {
262923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            // Obtain methods declared by super-interfaces too.
263923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            while (interfaceClass != null) {
264923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                addNonStaticPublicMethods(interfaceClass, expectedMethods);
265923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                interfaceClass = interfaceClass.getSuperclass();
266923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            }
267923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        }
268923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(expectedMethods.size(), declaredMethods.size());
269923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
270923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Check the method signatures are compatible.
271923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        for (Method expectedMethod : expectedMethods) {
272923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            Method actualMethod =
273923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                    lambdaClass.getMethod(expectedMethod.getName(),
274923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                            expectedMethod.getParameterTypes());
275923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            assertEquals(expectedMethod.getReturnType(), actualMethod.getReturnType());
276923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        }
277923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
278923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
279923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static void addNonStaticPublicMethods(Class<?> clazz, Set<Method> methodSet) {
280923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        for (Method interfaceMethod : clazz.getDeclaredMethods()) {
281923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            int modifiers = interfaceMethod.getModifiers();
282923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            if ((!Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
283923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                methodSet.add(interfaceMethod);
284923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            }
285923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        }
286923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
287923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
288923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static void assertNonSerializableLambdaCharacteristics(Object r1) throws Exception {
289923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        ByteArrayOutputStream baos = new ByteArrayOutputStream();
290923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        try (ObjectOutputStream os = new ObjectOutputStream(baos)) {
291923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            os.writeObject(r1);
292923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            os.flush();
293923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            fail();
294923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        } catch (NotSerializableException expected) {
295923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        }
296923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
297923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
298ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller    /**
299ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller     * Asserts that necessary conditions hold when there are two lambdas with separate but identical
300ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller     * definitions.
301ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller     */
302ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller    private static void assertMultipleDefinitionCharacteristics(
303ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            Callable<String> r1, Callable<String> r2) throws Exception {
304ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller
305ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        // Sanity check that the lambdas do the same thing.
306ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertEquals(r1.call(), r2.call());
307923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
308afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // Two lambdas from different definitions can share the same class or may not so there are
309afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // no assertions about the classes for the instances. See JLS 15.27.4.
310afaca2675a3cd159ef0d210476926c0085895136Neil Fuller
311afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // We cannot assert anything about the reference equality or equals() behavior of the
312afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // instances themselves either.
313afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // Implementations are free to return the same object or different if the lambdas are
314afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // equivalent.  It may affect collections behavior so no code should assume anything about
315afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // the identity of the lambda instance.
316afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // See the JSR-000335, Part E: Typing and Evaluation. Sharing of stateless instances is not
317afaca2675a3cd159ef0d210476926c0085895136Neil Fuller        // explicitly called out in the JLS.
318ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller    }
319ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller
320ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller    /**
321ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller     * Asserts that necessary conditions hold when there are two lambdas created from the same
322ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller     * definition.
323ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller     */
324ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller    private static void assertMultipleInstanceCharacteristics(
325ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller            Callable<String> r1, Callable<String> r2) throws Exception {
326ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller
327ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        // Sanity check that the lambdas do the same thing.
328ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        assertEquals(r1.call(), r2.call());
329ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller
330ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        // There doesn't appear to be anything else that is safe to assert here. Two lambdas
331ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        // created from the same definition can be the same, as can their class, but they can also
332ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        // be different. See JLS 15.27.4.
333923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
334923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
335923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static void assertGeneralLambdaClassCharacteristics(Object r1) throws Exception {
336923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Class<?> lambdaClass = r1.getClass();
337923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
338923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Lambda objects have classes that have names.
339923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNotNull(lambdaClass.getName());
340923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNotNull(lambdaClass.getSimpleName());
341923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNotNull(lambdaClass.getCanonicalName());
342923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
343923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Lambda classes are "synthetic classes" that are not arrays.
344923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(lambdaClass.isAnnotation());
345923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(lambdaClass.isInterface());
346923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(lambdaClass.isArray());
347923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(lambdaClass.isEnum());
348923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(lambdaClass.isPrimitive());
349923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertTrue(lambdaClass.isSynthetic());
350923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNull(lambdaClass.getComponentType());
351923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
352923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Expected modifiers
353923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        int classModifiers = lambdaClass.getModifiers();
354923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertTrue(Modifier.isFinal(classModifiers));
355923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
356ebca9ee057f3eeef1d50289693a11b59baf0f890Neil Fuller        // We have seen optimizations that make lambdas public so we do not make any assertions
357ebca9ee057f3eeef1d50289693a11b59baf0f890Neil Fuller        // about class visibility: they can be package-private or public. http://b/73255857
358ebca9ee057f3eeef1d50289693a11b59baf0f890Neil Fuller
359923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Unexpected modifiers
360923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isPrivate(classModifiers));
361923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isProtected(classModifiers));
362923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isStatic(classModifiers));
363923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isSynchronized(classModifiers));
364923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isVolatile(classModifiers));
365923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isTransient(classModifiers));
366923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isNative(classModifiers));
367923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isInterface(classModifiers));
368923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isAbstract(classModifiers));
369923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(Modifier.isStrict(classModifiers));
370923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
371923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Check the classloader, inheritance hierarchy and package.
372923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertSame(LambdaImplementationTest.class.getClassLoader(), lambdaClass.getClassLoader());
373923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertSame(Object.class, lambdaClass.getSuperclass());
374923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertSame(Object.class, lambdaClass.getGenericSuperclass());
375923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(LambdaImplementationTest.class.getPackage(), lambdaClass.getPackage());
376923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
377923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Check the implementation of the non-final public methods that all Objects possess.
378923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNotNull(r1.toString());
379923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertTrue(r1.equals(r1));
380923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(System.identityHashCode(r1), r1.hashCode());
381923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
382923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
383923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static <T> void assertLambdaMethodCharacteristics(T r1, Class<?> samInterfaceClass)
384923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            throws Exception {
385923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Find the single abstract method on the interface.
386923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Method singleAbstractMethod = null;
387923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        for (Method method : samInterfaceClass.getDeclaredMethods()) {
388923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            if (Modifier.isAbstract(method.getModifiers())) {
389923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                singleAbstractMethod = method;
390923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                break;
391923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            }
392923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        }
393923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertNotNull(singleAbstractMethod);
394923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
395923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        // Confirm the lambda implements the method as expected.
396923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Method implementationMethod = r1.getClass().getMethod(
397923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller                singleAbstractMethod.getName(), singleAbstractMethod.getParameterTypes());
398923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertSame(singleAbstractMethod.getReturnType(), implementationMethod.getReturnType());
399923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertSame(r1.getClass(), implementationMethod.getDeclaringClass());
400923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(implementationMethod.isSynthetic());
401923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(implementationMethod.isBridge());
402923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertFalse(implementationMethod.isDefault());
403923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
404923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
405923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static String staticMethod() {
406ab09ee69a6fdf14d828a6089ccb0261a6463ad0bNeil Fuller        return STATIC_METHOD_RESPONSE;
407923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
408923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
409923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private interface MarkerInterface {
410923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
411923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
412923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    private static <T> void assertCallableBehavior(Callable<T> r1, T expectedResult)
413923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller            throws Exception {
414923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(expectedResult, r1.call());
415923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
416923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Method implCallMethod = r1.getClass().getDeclaredMethod("call");
417923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(expectedResult, implCallMethod.invoke(r1));
418923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller
419923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        Method interfaceCallMethod = Callable.class.getDeclaredMethod("call");
420923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller        assertEquals(expectedResult, interfaceCallMethod.invoke(r1));
421923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller    }
422923866595bd9ed27eff087d61843299f387ff5d9Neil Fuller}
423