1 /*
2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * @test
26  * @bug 8242451
27  * @library /test/lib
28  * @summary Test that the LAMBDA_INSTANCE$ field is present depending
29  *          on disableEagerInitialization
30  * @run main LambdaEagerInitTest
31  * @run main/othervm -Djdk.internal.lambda.disableEagerInitialization=true LambdaEagerInitTest
32  */
33 
34 import java.lang.reflect.Field;
35 import java.lang.reflect.Modifier;
36 import java.util.Arrays;
37 import java.util.HashSet;
38 import java.util.Set;
39 import java.util.stream.Collectors;
40 
41 import static jdk.test.lib.Asserts.*;
42 
43 public class LambdaEagerInitTest {
44 
45     interface H {Object m(String s);}
46 
47     private static Set<String> allowedStaticFields(boolean nonCapturing) {
48         Set<String> s = new HashSet<>();
49         if (Boolean.getBoolean("jdk.internal.lambda.disableEagerInitialization")) {
50             if (nonCapturing) s.add("LAMBDA_INSTANCE$");
51         }
52         return s;
53     }
54 
55     private void nonCapturingLambda() {
56         H la = s -> s;
57         assertEquals("hi", la.m("hi"));
58         Class<? extends H> c1 = la.getClass();
59         verifyLambdaClass(la.getClass(), true);
60     }
61 
62     private void capturingLambda() {
63         H la = s -> concat(s, "foo");
64         assertEquals("hi foo", la.m("hi"));
65         verifyLambdaClass(la.getClass(), false);
66     }
67 
68     private void verifyLambdaClass(Class<?> c, boolean nonCapturing) {
69         Set<String> staticFields = new HashSet<>();
70         Set<String> instanceFields = new HashSet<>();
71         for (Field f : c.getDeclaredFields()) {
72             if (Modifier.isStatic(f.getModifiers())) {
73                 staticFields.add(f.getName());
74             } else {
75                 instanceFields.add(f.getName());
76             }
77         }
78         assertEquals(instanceFields.size(), nonCapturing ? 0 : 1, "Unexpected instance fields");
79         assertEquals(staticFields, allowedStaticFields(nonCapturing), "Unexpected static fields");
80     }
81 
82     private String concat(String... ss) {
83         return Arrays.stream(ss).collect(Collectors.joining(" "));
84     }
85 
86     public static void main(String[] args) {
87         LambdaEagerInitTest test = new LambdaEagerInitTest();
88         test.nonCapturingLambda();
89         test.capturingLambda();
90     }
91 }
92