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 8173898
27  * @summary Basic test for checking filtering of reflection frames
28  * @run testng ReflectionFrames
29  */
30 
31 package test.java.lang.StackWalker;
32 
33 import java.lang.StackWalker.StackFrame;
34 import java.lang.reflect.Constructor;
35 import java.lang.reflect.Method;
36 import java.lang.invoke.MethodHandle;
37 import java.lang.invoke.MethodHandles;
38 import java.lang.invoke.MethodHandles.Lookup;
39 import java.lang.invoke.MethodType;
40 import java.util.EnumSet;
41 import java.util.List;
42 import java.util.function.Supplier;
43 import java.util.stream.Collectors;
44 import java.util.stream.Stream;
45 import static java.lang.StackWalker.Option.*;
46 
47 import org.testng.annotations.DataProvider;
48 import org.testng.annotations.Test;
49 import static org.testng.Assert.*;
50 
51 public class ReflectionFrames {
52     final static boolean verbose = false;
53     // Android-changed: libcore has different internal implementation for reflection.
54     // final static Class<?> REFLECT_ACCESS = findClass("java.lang.reflect.ReflectAccess");
55     // final static Class<?> REFLECTION_FACTORY = findClass("jdk.internal.reflect.ReflectionFactory");
56     final static Class<?> REFLECT_ACCESS = findClass("java.lang.Class");
57 
findClass(String cn)58     private static Class<?> findClass(String cn) {
59         try {
60             return Class.forName(cn);
61         } catch (ClassNotFoundException e) {
62             throw new AssertionError(e);
63         }
64     }
65 
66     /**
67      * This test invokes new StackInspector() directly from
68      * the caller StackInspector.Caller.create method.
69      * It checks that the caller is StackInspector.Caller.
70      * It also checks the expected frames collected
71      * by walking the stack from the default StackInspector()
72      * constructor.
73      * This is done twice, once using a default StackWalker
74      * that hides reflection frames, once using a StackWalker
75      * configured to show reflection frames.
76      */
77     @Test
testNewStackInspector()78     public static void testNewStackInspector() throws Exception {
79         // Sets the default walker which hides reflection
80         // frames.
81         StackInspector.walker.set(StackInspector.walkerHide);
82 
83         // Calls the StackInspector.create method through reflection
84         // and check the frames collected in the StackInspector
85         // default constructor.
86         // The create method invokes new StackInspector() directly.
87         // No reflection frame should appear.
88         System.out.println("testNewStackInspector: create");
89 
90         StackInspector obj = ((StackInspector)StackInspector.Caller.class
91                              .getMethod("create", How.class)
92                              .invoke(null, How.NEW));
93         assertEquals(obj.collectedFrames,
94                      List.of(StackInspector.class.getName()
95                                  +"::<init>",
96                              StackInspector.Caller.class.getName()
97                                  +"::create",
98                              ReflectionFrames.class.getName()
99                                  +"::testNewStackInspector"));
100         assertEquals(obj.cls, StackInspector.Caller.class);
101         assertEquals(obj.filtered, 0);
102 
103         // Calls the StackInspector.reflect method through reflection
104         // and check the frames collected in the StackInspector
105         // default constructor.
106         // The reflect method invokes the create method through
107         // reflection.
108         // The create method invokes new StackInspector() directly.
109         // No reflection frame should appear.
110         System.out.println("testNewStackInspector: reflect");
111 
112         obj = ((StackInspector)StackInspector.Caller.class
113                              .getMethod("reflect", How.class)
114                              .invoke(null, How.NEW));
115         assertEquals(obj.collectedFrames,
116                      List.of(StackInspector.class.getName()
117                                  +"::<init>",
118                              StackInspector.Caller.class.getName()
119                                  +"::create",
120                              StackInspector.Caller.class.getName()
121                                  +"::reflect",
122                              ReflectionFrames.class.getName()
123                                  +"::testNewStackInspector"));
124         assertEquals(obj.cls, StackInspector.Caller.class);
125         assertEquals(obj.filtered, 0);
126 
127         // Calls the StackInspector.handle method through reflection
128         // and check the frames collected in the StackInspector
129         // default constructor.
130         // The handle method invokes the create method using
131         // a MethodHandle.
132         // The create method invokes new StackInspector() directly.
133         // No reflection frame should appear.
134         System.out.println("testNewStackInspector: handle");
135 
136         obj = ((StackInspector)StackInspector.Caller.class
137                              .getMethod("handle", How.class)
138                              .invoke(null, How.NEW));
139         assertEquals(obj.collectedFrames,
140                      List.of(StackInspector.class.getName()
141                                  +"::<init>",
142                              StackInspector.Caller.class.getName()
143                                  +"::create",
144                              StackInspector.Caller.class.getName()
145                                  +"::handle",
146                              ReflectionFrames.class.getName()
147                                  +"::testNewStackInspector"));
148         assertEquals(obj.cls, StackInspector.Caller.class);
149         assertEquals(obj.filtered, 0);
150 
151         // Sets a non-default walker configured to show
152         // reflection frames
153         StackInspector.walker.set(StackInspector.walkerShow);
154 
155         // Calls the StackInspector.create method through reflection
156         // and check the frames collected in the StackInspector
157         // default constructor.
158         // The create method invokes new StackInspector() directly.
159         // We should see all reflection frames, except the
160         // jdk.internal.reflect frames which we are filtering
161         // out in StackInspector::filter.
162         System.out.println("testNewStackInspector: create: show reflect");
163 
164         obj = ((StackInspector)StackInspector.Caller.class
165                              .getMethod("create", How.class)
166                              .invoke(null, How.NEW));
167         assertEquals(obj.collectedFrames,
168                      List.of(StackInspector.class.getName()
169                                  +"::<init>",
170                              StackInspector.Caller.class.getName()
171                                  +"::create",
172                              Method.class.getName()
173                                  +"::invoke",
174                              ReflectionFrames.class.getName()
175                                  +"::testNewStackInspector"));
176         assertEquals(obj.cls, StackInspector.Caller.class);
177         // Android-changed: libcore uses very little of jdk.internal.reflect.
178         // assertNotEquals(obj.filtered, 0);
179 
180         // Calls the StackInspector.reflect method through reflection
181         // and check the frames collected in the StackInspector
182         // default constructor.
183         // The reflect method invokes the create method through
184         // reflection.
185         // The create method invokes new StackInspector() directly.
186         // We should see all reflection frames, except the
187         // jdk.internal.reflect frames which we are filtering
188         // out in StackInspector::filter.
189         System.out.println("testNewStackInspector: reflect: show reflect");
190 
191         obj = ((StackInspector)StackInspector.Caller.class
192                              .getMethod("reflect", How.class)
193                              .invoke(null, How.NEW));
194         assertEquals(obj.collectedFrames,
195                      List.of(StackInspector.class.getName()
196                                  +"::<init>",
197                              StackInspector.Caller.class.getName()
198                                  +"::create",
199                              Method.class.getName()
200                                  +"::invoke",
201                              StackInspector.Caller.class.getName()
202                                  +"::reflect",
203                              Method.class.getName()
204                                  +"::invoke",
205                              ReflectionFrames.class.getName()
206                                  +"::testNewStackInspector"));
207         assertEquals(obj.cls, StackInspector.Caller.class);
208         // Android-changed: libcore uses very little of jdk.internal.reflect.
209         // assertNotEquals(obj.filtered, 0);
210 
211         // Calls the StackInspector.handle method through reflection
212         // and check the frames collected in the StackInspector
213         // default constructor.
214         // The handle method invokes the create method using
215         // MethodHandle.
216         // The create method invokes new StackInspector() directly.
217         // We should see all reflection frames, except the
218         // jdk.internal.reflect frames which we are filtering
219         // out in StackInspector::filter.
220         System.out.println("testNewStackInspector: handle: show reflect");
221 
222         obj = ((StackInspector)StackInspector.Caller.class
223                              .getMethod("handle", How.class)
224                              .invoke(null, How.NEW));
225         assertEquals(obj.collectedFrames,
226                      List.of(StackInspector.class.getName()
227                                  +"::<init>",
228                              StackInspector.Caller.class.getName()
229                                  +"::create",
230                              // MethodHandle::invoke remains hidden
231                              StackInspector.Caller.class.getName()
232                                  +"::handle",
233                              Method.class.getName()
234                                  +"::invoke",
235                              ReflectionFrames.class.getName()
236                                  +"::testNewStackInspector"));
237         assertEquals(obj.cls, StackInspector.Caller.class);
238         // Android-changed: libcore uses very little of jdk.internal.reflect.
239         // assertNotEquals(obj.filtered, 0);
240     }
241 
242    /**
243      * This test invokes Constructor.newInstance() from
244      * the caller StackInspector.Caller.create method.
245      * It checks that the caller is StackInspector.Caller.
246      * It also checks the expected frames collected
247      * by walking the stack from the default StackInspector()
248      * constructor.
249      * This is done twice, once using a default StackWalker
250      * that hides reflection frames, once using a StackWalker
251      * configured to show reflection frames.
252      */
253     @Test
testConstructor()254     public static void testConstructor() throws Exception {
255         // Sets the default walker which hides reflection
256         // frames.
257         StackInspector.walker.set(StackInspector.walkerHide);
258 
259         // Calls the StackInspector.create method through reflection
260         // and check the frames collected in the StackInspector
261         // default constructor.
262         // The create method invokes Constructor.newInstance().
263         // No reflection frame should appear.
264         System.out.println("testConstructor: create");
265 
266         StackInspector obj = ((StackInspector)StackInspector.Caller.class
267                              .getMethod("create", How.class)
268                              .invoke(null, How.CONSTRUCTOR));
269         assertEquals(obj.collectedFrames,
270                      List.of(StackInspector.class.getName()
271                                  +"::<init>",
272                              StackInspector.Caller.class.getName()
273                                  +"::create",
274                              ReflectionFrames.class.getName()
275                                  +"::testConstructor"));
276         assertEquals(obj.cls, StackInspector.Caller.class);
277         assertEquals(obj.filtered, 0);
278 
279         // Calls the StackInspector.reflect method through reflection
280         // and check the frames collected in the StackInspector
281         // default constructor.
282         // The reflect method invokes the create method through
283         // reflection.
284         // The create method invokes Constructor.newInstance().
285         // No reflection frame should appear.
286         System.out.println("testConstructor: reflect");
287 
288         obj = ((StackInspector)StackInspector.Caller.class
289                              .getMethod("reflect", How.class)
290                              .invoke(null, How.CONSTRUCTOR));
291         assertEquals(obj.collectedFrames,
292                      List.of(StackInspector.class.getName()
293                                  +"::<init>",
294                              StackInspector.Caller.class.getName()
295                                  +"::create",
296                              StackInspector.Caller.class.getName()
297                                  +"::reflect",
298                              ReflectionFrames.class.getName()
299                                  +"::testConstructor"));
300         assertEquals(obj.cls, StackInspector.Caller.class);
301         assertEquals(obj.filtered, 0);
302 
303         // Calls the StackInspector.handle method through reflection
304         // and check the frames collected in the StackInspector
305         // default constructor.
306         // The handle method invokes the create method using
307         // MethodHandle.
308         // The create method invokes Constructor.newInstance().
309         // No reflection frame should appear.
310         System.out.println("testConstructor: handle");
311 
312         obj = ((StackInspector)StackInspector.Caller.class
313                              .getMethod("handle", How.class)
314                              .invoke(null, How.CONSTRUCTOR));
315         assertEquals(obj.collectedFrames,
316                      List.of(StackInspector.class.getName()
317                                  +"::<init>",
318                              StackInspector.Caller.class.getName()
319                                  +"::create",
320                              StackInspector.Caller.class.getName()
321                                  +"::handle",
322                              ReflectionFrames.class.getName()
323                                  +"::testConstructor"));
324         assertEquals(obj.cls, StackInspector.Caller.class);
325         assertEquals(obj.filtered, 0);
326 
327         // Sets a non-default walker configured to show
328         // reflection frames
329         StackInspector.walker.set(StackInspector.walkerShow);
330 
331         // Calls the StackInspector.create method through reflection
332         // and check the frames collected in the StackInspector
333         // default constructor.
334         // The create method invokes Constructor.newInstance().
335         // We should see all reflection frames, except the
336         // jdk.internal.reflect frames which we are filtering
337         // out in StackInspector::filter.
338         System.out.println("testConstructor: create: show reflect");
339 
340         obj = ((StackInspector)StackInspector.Caller.class
341                              .getMethod("create", How.class)
342                              .invoke(null, How.CONSTRUCTOR));
343         assertEquals(obj.collectedFrames,
344                      List.of(StackInspector.class.getName()
345                                  +"::<init>",
346                              Constructor.class.getName()
347                                  // Android-changed: libcore internal implementation is different.
348                                  // +"::newInstanceWithCaller",
349                                  +"::newInstance0",
350                              Constructor.class.getName()
351                                  +"::newInstance",
352                              StackInspector.Caller.class.getName()
353                                  +"::create",
354                              Method.class.getName()
355                                  +"::invoke",
356                              ReflectionFrames.class.getName()
357                                  +"::testConstructor"));
358         assertEquals(obj.cls, StackInspector.Caller.class);
359         // Android-changed: libcore uses very little of jdk.internal.reflect.
360         // assertNotEquals(obj.filtered, 0);
361 
362         // Calls the StackInspector.reflect method through reflection
363         // and check the frames collected in the StackInspector
364         // default constructor.
365         // The reflect method invokes the create method through
366         // reflection.
367         // The create method invokes Constructor.newInstance().
368         // We should see all reflection frames, except the
369         // jdk.internal.reflect frames which we are filtering
370         // out in StackInspector::filter.
371         System.out.println("testConstructor: reflect: show reflect");
372 
373         obj = ((StackInspector)StackInspector.Caller.class
374                              .getMethod("reflect", How.class)
375                              .invoke(null, How.CONSTRUCTOR));
376         assertEquals(obj.collectedFrames,
377                      List.of(StackInspector.class.getName()
378                                  +"::<init>",
379                              Constructor.class.getName()
380                                  // Android-changed: libcore internal implementation is different.
381                                  // +"::newInstanceWithCaller",
382                                  +"::newInstance0",
383                              Constructor.class.getName()
384                                  +"::newInstance",
385                              StackInspector.Caller.class.getName()
386                                  +"::create",
387                              Method.class.getName()
388                                  +"::invoke",
389                              StackInspector.Caller.class.getName()
390                                  +"::reflect",
391                              Method.class.getName()
392                                  +"::invoke",
393                              ReflectionFrames.class.getName()
394                                  +"::testConstructor"));
395         assertEquals(obj.cls, StackInspector.Caller.class);
396         // Android-changed: libcore uses very little of jdk.internal.reflect.
397         // assertNotEquals(obj.filtered, 0);
398 
399         // Calls the StackInspector.handle method through reflection
400         // and check the frames collected in the StackInspector
401         // default constructor.
402         // The handle method invokes the create method using
403         // MethodHandle.
404         // The create method invokes Constructor.newInstance().
405         // We should see all reflection frames, except the
406         // jdk.internal.reflect frames which we are filtering
407         // out in StackInspector::filter.
408         System.out.println("testConstructor: handle: show reflect");
409 
410         obj = ((StackInspector)StackInspector.Caller.class
411                              .getMethod("handle", How.class)
412                              .invoke(null, How.CONSTRUCTOR));
413         assertEquals(obj.collectedFrames,
414                      List.of(StackInspector.class.getName()
415                                  +"::<init>",
416                              Constructor.class.getName()
417                                  // Android-changed: libcore internal implementation is different.
418                                  // +"::newInstanceWithCaller",
419                                  +"::newInstance0",
420                              Constructor.class.getName()
421                                  +"::newInstance",
422                              StackInspector.Caller.class.getName()
423                                  +"::create",
424                              // MethodHandle::invoke remains hidden
425                              StackInspector.Caller.class.getName()
426                                  +"::handle",
427                              Method.class.getName()
428                                  +"::invoke",
429                              ReflectionFrames.class.getName()
430                                  +"::testConstructor"));
431         assertEquals(obj.cls, StackInspector.Caller.class);
432         // Android-changed: libcore uses very little of jdk.internal.reflect.
433         // assertNotEquals(obj.filtered, 0);
434     }
435 
436    /**
437      * This test invokes StackInspector.class.newInstance() from
438      * the caller StackInspector.Caller.create method. Because
439      * Class.newInstance() is not considered as a
440      * reflection frame, the the caller returned by
441      * getCallerClass() should appear to be java.lang.Class
442      * and not StackInspector.Caller.
443      * It also checks the expected frames collected
444      * by walking the stack from the default StackInspector()
445      * constructor.
446      * This is done twice, once using a default StackWalker
447      * that hides reflection frames, once using a StackWalker
448      * configured to show reflection frames.
449      */
450     @Test
testNewInstance()451     public static void testNewInstance() throws Exception {
452         // Sets the default walker which hides reflection
453         // frames.
454         StackInspector.walker.set(StackInspector.walkerHide);
455 
456         // Calls the StackInspector.create method through reflection
457         // and check the frames collected in the StackInspector
458         // default constructor.
459         // The create method invokes StackInspector.class.newInstance().
460         // No reflection frame should appear, except
461         // Class::newInstance which is not considered as
462         // a reflection frame.
463         System.out.println("testNewInstance: create");
464 
465         StackInspector obj = ((StackInspector)StackInspector.Caller.class
466                              .getMethod("create", How.class)
467                              .invoke(null, How.CLASS));
468         assertEquals(obj.collectedFrames,
469                      List.of(StackInspector.class.getName()
470                                  +"::<init>",
471                              // Android-changed: libcore internal implementation is different.
472                              // REFLECT_ACCESS.getName()
473                              //     +"::newInstance",
474                              // REFLECTION_FACTORY.getName()
475                              //     +"::newInstance",
476                              Class.class.getName()
477                                  +"::newInstance",
478                              StackInspector.Caller.class.getName()
479                                  +"::create",
480                              ReflectionFrames.class.getName()
481                                  +"::testNewInstance"));
482         // Because implementation frames are not filtered, then the
483         // caller is ReflectAccess.class
484         assertEquals(obj.cls, REFLECT_ACCESS);
485         assertEquals(obj.filtered, 0);
486 
487         // Calls the StackInspector.reflect method through reflection
488         // and check the frames collected in the StackInspector
489         // default constructor.
490         // The reflect method invokes the create method through
491         // reflection.
492         // The create method invokes StackInspector.class.newInstance().
493         // No reflection frame should appear, except
494         // Class::newInstance which is not considered as
495         // a reflection frame.
496         System.out.println("testNewInstance: reflect");
497 
498         obj = ((StackInspector)StackInspector.Caller.class
499                              .getMethod("reflect", How.class)
500                              .invoke(null, How.CLASS));
501         assertEquals(obj.collectedFrames,
502                      List.of(StackInspector.class.getName()
503                                  +"::<init>",
504                              // Android-changed: libcore internal implementation is different.
505                              // REFLECT_ACCESS.getName()
506                              //     +"::newInstance",
507                              // REFLECTION_FACTORY.getName()
508                              //     +"::newInstance",
509                              Class.class.getName()
510                                  +"::newInstance",
511                              StackInspector.Caller.class.getName()
512                                  +"::create",
513                              StackInspector.Caller.class.getName()
514                                  +"::reflect",
515                              ReflectionFrames.class.getName()
516                                  +"::testNewInstance"));
517 
518         // Because implementation frames are not filtered, then the
519         // caller is ReflectAccess.class
520         assertEquals(obj.cls, REFLECT_ACCESS);
521         assertEquals(obj.filtered, 0);
522 
523         // Calls the StackInspector.handle method through reflection
524         // and check the frames collected in the StackInspector
525         // default constructor.
526         // The handle method invokes the create method using
527         // reflection.
528         // The create method invokes StackInspector.class.newInstance().
529         // No reflection frame should appear, except
530         // Class::newInstance which is not considered as
531         // a reflection frame.
532         System.out.println("testNewInstance: handle");
533 
534         obj = ((StackInspector)StackInspector.Caller.class
535                              .getMethod("handle", How.class)
536                              .invoke(null, How.CLASS));
537         assertEquals(obj.collectedFrames,
538                      List.of(StackInspector.class.getName()
539                                  +"::<init>",
540                              // Android-changed: libcore internal implementation is different.
541                              // REFLECT_ACCESS.getName()
542                              //     +"::newInstance",
543                              // REFLECTION_FACTORY.getName()
544                              //     +"::newInstance",
545                              Class.class.getName()
546                                  +"::newInstance",
547                              StackInspector.Caller.class.getName()
548                                  +"::create",
549                              StackInspector.Caller.class.getName()
550                                  +"::handle",
551                              ReflectionFrames.class.getName()
552                                  +"::testNewInstance"));
553 
554         // Because implementation frames are not filtered, then the
555         // caller is ReflectAccess.class
556         assertEquals(obj.cls, REFLECT_ACCESS);
557         assertEquals(obj.filtered, 0);
558 
559         // Sets a non-default walker configured to show
560         // reflection frames
561         StackInspector.walker.set(StackInspector.walkerShow);
562 
563         // Calls the StackInspector.create method through reflection
564         // and check the frames collected in the StackInspector
565         // default constructor.
566         // The create method invokes StackInspector.class.newInstance().
567         // We should see all reflection frames, except the
568         // jdk.internal.reflect frames which we are filtering
569         // out in StackInspector::filter.
570         System.out.println("testNewInstance: create: show reflect");
571 
572         obj = ((StackInspector)StackInspector.Caller.class
573                              .getMethod("create", How.class)
574                              .invoke(null, How.CLASS));
575         assertEquals(obj.collectedFrames,
576                      List.of(StackInspector.class.getName()
577                                  +"::<init>",
578                              // Android-changed: libcore internal implementation is different.
579                              // Constructor.class.getName()
580                                  // +"::newInstanceWithCaller",
581                              // REFLECT_ACCESS.getName()
582                              //     +"::newInstance",
583                              Class.class.getName()
584                                  +"::newInstance",
585                              StackInspector.Caller.class.getName()
586                                  +"::create",
587                              Method.class.getName()
588                                  +"::invoke",
589                              ReflectionFrames.class.getName()
590                                  +"::testNewInstance"));
591         // Because implementation frames are not filtered, then the
592         // caller is ReflectAccess.class
593         assertEquals(obj.cls, REFLECT_ACCESS);
594         // Android-changed: libcore uses very little of jdk.internal.reflect.
595         // assertNotEquals(obj.filtered, 0);
596 
597         // Calls the StackInspector.reflect method through reflection
598         // and check the frames collected in the StackInspector
599         // default constructor.
600         // The reflect method invokes the create method through
601         // reflection.
602         // The create method invokes StackInspector.class.newInstance().
603         // We should see all reflection frames, except the
604         // jdk.internal.reflect frames which we are filtering
605         // out in StackInspector::filter.
606         System.out.println("testNewInstance: reflect: show reflect");
607 
608         obj = ((StackInspector)StackInspector.Caller.class
609                              .getMethod("reflect", How.class)
610                              .invoke(null, How.CLASS));
611         System.out.println(obj.collectedFrames);
612         assertEquals(obj.collectedFrames,
613                      List.of(StackInspector.class.getName()
614                                  +"::<init>",
615                              // Android-changed: libcore internal implementation is different.
616                              // Constructor.class.getName()
617                                  // +"::newInstanceWithCaller",
618                              // REFLECT_ACCESS.getName()
619                              //     +"::newInstance",
620                              Class.class.getName()
621                                  +"::newInstance",
622                              StackInspector.Caller.class.getName()
623                                  +"::create",
624                              Method.class.getName()
625                                  +"::invoke",
626                              StackInspector.Caller.class.getName()
627                                  +"::reflect",
628                              Method.class.getName()
629                                  +"::invoke",
630                              ReflectionFrames.class.getName()
631                                  +"::testNewInstance"));
632 
633         // Because implementation frames are not filtered, then the
634         // caller is ReflectAccess.class
635         assertEquals(obj.cls, REFLECT_ACCESS);
636         // Android-changed: libcore uses very little of jdk.internal.reflect.
637         // assertNotEquals(obj.filtered, 0);
638 
639         // Calls the StackInspector.handle method through reflection
640         // and check the frames collected in the StackInspector
641         // default constructor.
642         // The handle method invokes the create method using
643         // MethodHandle.
644         // The create method invokes StackInspector.class.newInstance().
645         // We should see all reflection frames, except the
646         // jdk.internal.reflect frames which we are filtering
647         // out in StackInspector::filter.
648         System.out.println("testNewInstance: handle: show reflect");
649 
650         obj = ((StackInspector)StackInspector.Caller.class
651                              .getMethod("handle", How.class)
652                              .invoke(null, How.CLASS));
653         assertEquals(obj.collectedFrames,
654                      List.of(StackInspector.class.getName()
655                                  +"::<init>",
656                              // Android-changed: libcore internal implementation is different.
657                              // Constructor.class.getName()
658                                  // +"::newInstanceWithCaller",
659                              // REFLECT_ACCESS.getName()
660                              //     +"::newInstance",
661                              Class.class.getName()
662                                  +"::newInstance",
663                              StackInspector.Caller.class.getName()
664                                  +"::create",
665                              // MethodHandle::invoke remains hidden
666                              StackInspector.Caller.class.getName()
667                                  +"::handle",
668                              Method.class.getName()
669                                  +"::invoke",
670                              ReflectionFrames.class.getName()
671                                  +"::testNewInstance"));
672 
673         // Because implementation frames are not filtered, then the
674         // caller is ReflectAccess.class
675         assertEquals(obj.cls, REFLECT_ACCESS);
676         // Android-changed: libcore uses very little of jdk.internal.reflect.
677         // assertNotEquals(obj.filtered, 0);
678     }
679 
680     @Test
testGetCaller()681     public static void testGetCaller() throws Exception {
682         // Sets the default walker which hides reflection
683         // frames.
684         StackInspector.walker.set(StackInspector.walkerHide);
685 
686         assertEquals(StackInspector.getCaller(), ReflectionFrames.class);
687         assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),
688                      ReflectionFrames.class);
689 
690         // Sets a non-default walker configured to show
691         // reflection frames
692         StackInspector.walker.set(StackInspector.walkerShow);
693 
694         assertEquals(StackInspector.getCaller(), ReflectionFrames.class);
695         assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),
696                      ReflectionFrames.class);
697     }
698 
699     @Test
testReflectCaller()700     public static void testReflectCaller() throws Exception {
701         // Sets the default walker which hides reflection
702         // frames.
703         StackInspector.walker.set(StackInspector.walkerHide);
704 
705         assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);
706         assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),
707                      ReflectionFrames.class);
708 
709         // Sets a non-default walker configured to show
710         // reflection frames
711         StackInspector.walker.set(StackInspector.walkerShow);
712 
713         assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);
714         assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),
715                      ReflectionFrames.class);
716     }
717 
718     // Android-changed: Android desugars lambda and thus the caller is different.
719     @Test(enabled = false)
testSupplyCaller()720     public static void testSupplyCaller() throws Exception {
721         // Sets the default walker which hides reflection
722         // frames.
723         StackInspector.walker.set(StackInspector.walkerHide);
724 
725         assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);
726         assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),
727                      ReflectionFrames.class);
728 
729         // Sets a non-default walker configured to show
730         // reflection frames
731         StackInspector.walker.set(StackInspector.walkerShow);
732 
733         assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);
734         assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),
735                      ReflectionFrames.class);
736     }
737 
738     @Test
testHandleCaller()739     public static void testHandleCaller() throws Exception {
740         // Sets the default walker which hides reflection
741         // frames.
742         StackInspector.walker.set(StackInspector.walkerHide);
743 
744         assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);
745         assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),
746                      ReflectionFrames.class);
747 
748         // Sets a non-default walker configured to show
749         // reflection frames
750         StackInspector.walker.set(StackInspector.walkerShow);
751 
752         assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);
753         assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),
754                      ReflectionFrames.class);
755     }
756 
757     static enum How { NEW, CONSTRUCTOR, CLASS};
758 
759     /**
760      * An object that collect stack frames by walking the stack
761      * (and calling getCallerClass()) from within its constructor.
762      * For the purpose of this test, StackInspector objects are
763      * always created from the nested StackInspector.Caller class,
764      * which should therefore appear as the caller of the
765      * StackInspector constructor.
766      */
767     static class StackInspector {
768         static final StackWalker walkerHide =
769             StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
770         static final StackWalker walkerShow =
771             StackWalker.getInstance(EnumSet.of(
772                            StackWalker.Option.RETAIN_CLASS_REFERENCE,
773                            StackWalker.Option.SHOW_REFLECT_FRAMES));
774         final static ThreadLocal<StackWalker> walker = new ThreadLocal<>() {
775              protected StackWalker initialValue() {
776                  return walkerHide;
777              }
778         };
779 
780         List<String> collectedFrames;
781         Class<?> cls = null;
782         boolean stop;
783         int filtered;
784         final boolean filterImplFrames;
785 
StackInspector()786         public StackInspector() {
787             stop = false;
788             // if reflection frames are not hidden, we want to
789             // filter implementation frames before collecting
790             // to avoid depending on internal details.
791             filterImplFrames = walker.get() == walkerShow;
792             collectedFrames = walker.get().walk(this::parse);
793             cls = walker.get().getCallerClass();
794         }
795 
collectedFrames()796         public List<String> collectedFrames() {
797             return collectedFrames;
798         }
799 
800         // The takeWhile method arrange for stopping frame collection
801         // as soon as a frame from ReflectionFrames.class is reached.
802         // The first such frame encountered is still included in the
803         // collected frames, but collection stops right after.
804         // This makes it possible to filter out anything above the
805         // the test method frame, such as frames from the test
806         // framework.
takeWhile(StackFrame f)807         public boolean takeWhile(StackFrame f) {
808             if (stop) return false;
809             if (verbose) System.out.println("    " + f);
810             stop = stop || f.getDeclaringClass() == ReflectionFrames.class;
811             return true;
812         }
813 
814         // filter out implementation frames to avoid depending
815         // on implementation details. If present, Class::newInstance,
816         // Method::invoke and Constructor::newInstance will
817         // still appear in the collected frames, which is
818         // sufficient for the purpose of the test.
819         // In the case where the StackWalker itself is supposed to
820         // filter the reflection frames, then this filter will always
821         // return true. This way, if such a reflection frame appears when
822         // it sjould have been filtered by StackWalker, it will make the
823         // test fail.
filter(StackFrame f)824         public boolean filter(StackFrame f) {
825             if (filterImplFrames &&
826                 f.getClassName().startsWith("jdk.internal.reflect.")) {
827                 filtered++;
828                 return false;
829             }
830             if (!verbose) System.out.println("    " + f);
831             return true;
832         }
833 
frame(StackFrame f)834         public String frame(StackFrame f) {
835             return f.getClassName() + "::" + f.getMethodName();
836         }
837 
parse(Stream<StackFrame> s)838         List<String> parse(Stream<StackFrame> s) {
839             // Android-changed: libcore doesn't have Stream.takeWhile method yet.
840             // return s.takeWhile(this::takeWhile)
841             return s.filter(this::takeWhile)
842                     .filter(this::filter)
843                     .map(this::frame)
844                     .collect(Collectors.toList());
845         }
846 
847         /**
848          * The Caller class is used to create instances of
849          * StackInspector, either direcltly, or throug reflection.
850          */
851         public static class Caller {
create(How how)852             public static StackInspector create(How how) throws Exception {
853                 switch(how) {
854                     case NEW: return new StackInspector();
855                     case CONSTRUCTOR: return StackInspector.class
856                         .getConstructor().newInstance();
857                     case CLASS: return StackInspector.class.newInstance();
858                     default: throw new AssertionError(String.valueOf(how));
859                 }
860             }
reflect(How how)861             public static StackInspector reflect(How how) throws Exception {
862                 return (StackInspector) Caller.class.getMethod("create", How.class)
863                       .invoke(null, how);
864             }
handle(How how)865             public static StackInspector handle(How how) throws Exception {
866                 Lookup lookup = MethodHandles.lookup();
867                 MethodHandle mh = lookup.findStatic(Caller.class, "create",
868                         MethodType.methodType(StackInspector.class, How.class));
869                 try {
870                     return (StackInspector) mh.invoke(how);
871                 } catch (Error | Exception x) {
872                     throw x;
873                 } catch(Throwable t) {
874                     throw new AssertionError(t);
875                 }
876             }
877         }
878 
getCaller()879         public static Class<?> getCaller() throws Exception {
880             return walker.get().getCallerClass();
881         }
882 
reflectCaller()883         public static Class<?> reflectCaller() throws Exception {
884             return (Class<?>)StackWalker.class.getMethod("getCallerClass")
885                 .invoke(walker.get());
886         }
887 
supplyCaller()888         public static Class<?> supplyCaller() throws Exception {
889             return ((Supplier<Class<?>>)StackInspector.walker.get()::getCallerClass).get();
890         }
891 
handleCaller()892         public static Class<?> handleCaller() throws Exception {
893             Lookup lookup = MethodHandles.lookup();
894             MethodHandle mh = lookup.findVirtual(StackWalker.class, "getCallerClass",
895                     MethodType.methodType(Class.class));
896             try {
897                 return (Class<?>) mh.invoke(walker.get());
898             } catch (Error | Exception x) {
899                 throw x;
900             } catch(Throwable t) {
901                 throw new AssertionError(t);
902             }
903         }
904     }
905 }
906