1 /*
2  * Copyright (c) 2017, 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 8173587
27  * @summary metafactory should fail if the method name is not legal
28  */
29 import java.lang.invoke.*;
30 import java.util.*;
31 
32 public class MetafactoryMethodNameTest {
33 
main(String... args)34     public static void main(String... args) {
35         goodName("x");
36         goodName("xy");
37 
38         goodName("]");
39         goodName("x]");
40         goodName("]y");
41         goodName("x]y");
42 
43         goodName("&");
44         goodName("x&");
45         goodName("&y");
46         goodName("x&y");
47 
48         badName(".");
49         badName("x.");
50         badName(".y");
51         badName("x.y");
52 
53         badName(";");
54         badName("x;");
55         badName(";y");
56         badName("x;y");
57 
58         badName("[");
59         badName("x[");
60         badName("[y");
61         badName("x[y");
62 
63         badName("/");
64         badName("x/");
65         badName("/y");
66         badName("x/y");
67 
68         badName("<");
69         badName("x<");
70         badName("<y");
71         badName("x<y");
72 
73         badName(">");
74         badName("x>");
75         badName(">y");
76         badName("x>y");
77 
78         badName("");
79         badName("<init>");
80         badName("<clinit>");
81     }
82 
mt(Class<?> ret, Class<?>... params)83     static MethodType mt(Class<?> ret, Class<?>... params) {
84         return MethodType.methodType(ret, params);
85     }
86 
smh(Class<?> c, String name, MethodType desc)87     static MethodHandle smh(Class<?> c, String name, MethodType desc) {
88         try {
89             return MethodHandles.lookup().findStatic(c, name, desc);
90         } catch (ReflectiveOperationException e) {
91             throw new RuntimeException(e);
92         }
93     }
94 
arr(Object... args)95     static Object[] arr(Object... args) {
96         return args;
97     }
98 
99     public static class C {
m()100         public static void m() {}
101     }
102 
103     public interface I {}
104 
105     private static MethodHandles.Lookup lookup = MethodHandles.lookup();
106     private static MethodType toI = mt(I.class);
107     private static MethodType toVoid = mt(void.class);
108     private static MethodHandle mh = smh(C.class, "m", toVoid);
109     private static Class<?> lce = LambdaConversionException.class;
110 
goodName(String name)111     static void goodName(String name) {
112         succeedMFLinkage(lookup, name, toI, toVoid, mh, toVoid);
113         succeedAltMFLinkage(lookup, name, toI, arr(toVoid, mh, toVoid, LambdaMetafactory.FLAG_SERIALIZABLE));
114     }
115 
badName(String name)116     static void badName(String name) {
117         failMFLinkage(lookup, name, toI, toVoid, mh, toVoid, lce);
118         failAltMFLinkage(lookup, name, toI, arr(toVoid, mh, toVoid, LambdaMetafactory.FLAG_SERIALIZABLE), lce);
119     }
120 
succeedMFLinkage(MethodHandles.Lookup lookup, String name, MethodType capType, MethodType desc, MethodHandle impl, MethodType checked)121     static CallSite succeedMFLinkage(MethodHandles.Lookup lookup,
122                                     String name,
123                                     MethodType capType,
124                                     MethodType desc,
125                                     MethodHandle impl,
126                                     MethodType checked) {
127         try {
128             return LambdaMetafactory.metafactory(lookup, name, capType, desc, impl, checked);
129         } catch (Throwable t) {
130             String msg = String.format("Unexpected exception during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
131                     lookup, name, capType, desc, impl, checked);
132             throw new AssertionError(msg, t);
133         }
134     }
135 
failMFLinkage(MethodHandles.Lookup lookup, String name, MethodType capType, MethodType desc, MethodHandle impl, MethodType checked, Class<?> expectedExceptionType)136     static void failMFLinkage(MethodHandles.Lookup lookup,
137                               String name,
138                               MethodType capType,
139                               MethodType desc,
140                               MethodHandle impl,
141                               MethodType checked,
142                               Class<?> expectedExceptionType) {
143         try {
144             LambdaMetafactory.metafactory(lookup, name, capType, desc, impl, checked);
145         } catch (Throwable t) {
146             if (expectedExceptionType.isInstance(t)) {
147                 return;
148             } else {
149                 String msg = String.format("Unexpected exception: expected %s during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
150                         expectedExceptionType.getName(),
151                         lookup, name, capType, desc, impl, checked);
152                 throw new AssertionError(msg, t);
153             }
154         }
155         String msg = String.format("Unexpected success: expected %s during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
156                 expectedExceptionType.getName(),
157                 lookup, name, capType, desc, impl, checked);
158         throw new AssertionError(msg);
159     }
160 
succeedAltMFLinkage(MethodHandles.Lookup lookup, String name, MethodType capType, Object[] args)161     static CallSite succeedAltMFLinkage(MethodHandles.Lookup lookup,
162                                         String name,
163                                         MethodType capType,
164                                         Object[] args) {
165         try {
166             return LambdaMetafactory.altMetafactory(lookup, name, capType, args);
167         } catch (Throwable t) {
168             String msg = String.format("Unexpected exception during linkage for metafactory(%s, %s, %s, %s)",
169                     lookup, name, capType, Arrays.asList(args));
170             throw new AssertionError(msg, t);
171         }
172     }
173 
failAltMFLinkage(MethodHandles.Lookup lookup, String name, MethodType capType, Object[] args, Class<?> expectedExceptionType)174     static void failAltMFLinkage(MethodHandles.Lookup lookup,
175                                  String name,
176                                  MethodType capType,
177                                  Object[] args,
178                                  Class<?> expectedExceptionType) {
179         try {
180             LambdaMetafactory.altMetafactory(lookup, name, capType, args);
181         } catch (Throwable t) {
182             if (expectedExceptionType.isInstance(t)) {
183                 return;
184             } else {
185                 String msg = String.format("Unexpected exception: expected %s during linkage for metafactory(%s, %s, %s, %s)",
186                         expectedExceptionType.getName(),
187                         lookup, name, capType, Arrays.asList(args));
188                 throw new AssertionError(msg, t);
189             }
190         }
191         String msg = String.format("Unexpected success: expected %s during linkage for metafactory(%s, %s, %s, %s)",
192                 expectedExceptionType.getName(),
193                 lookup, name, capType, Arrays.asList(args));
194         throw new AssertionError(msg);
195     }
196 
197 }
198