Path: blob/master/test/jdk/java/lang/StackWalker/ReflectionFrames.java
41149 views
/*1* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 817389826* @summary Basic test for checking filtering of reflection frames27* @run testng ReflectionFrames28*/2930import java.lang.StackWalker.StackFrame;31import java.lang.reflect.Constructor;32import java.lang.reflect.Method;33import java.lang.invoke.MethodHandle;34import java.lang.invoke.MethodHandles;35import java.lang.invoke.MethodHandles.Lookup;36import java.lang.invoke.MethodType;37import java.util.EnumSet;38import java.util.List;39import java.util.function.Supplier;40import java.util.stream.Collectors;41import java.util.stream.Stream;42import static java.lang.StackWalker.Option.*;4344import org.testng.annotations.DataProvider;45import org.testng.annotations.Test;46import static org.testng.Assert.*;4748public class ReflectionFrames {49final static boolean verbose = false;50final static Class<?> REFLECT_ACCESS = findClass("java.lang.reflect.ReflectAccess");51final static Class<?> REFLECTION_FACTORY = findClass("jdk.internal.reflect.ReflectionFactory");5253private static Class<?> findClass(String cn) {54try {55return Class.forName(cn);56} catch (ClassNotFoundException e) {57throw new AssertionError(e);58}59}6061/**62* This test invokes new StackInspector() directly from63* the caller StackInspector.Caller.create method.64* It checks that the caller is StackInspector.Caller.65* It also checks the expected frames collected66* by walking the stack from the default StackInspector()67* constructor.68* This is done twice, once using a default StackWalker69* that hides reflection frames, once using a StackWalker70* configured to show reflection frames.71*/72@Test73public static void testNewStackInspector() throws Exception {74// Sets the default walker which hides reflection75// frames.76StackInspector.walker.set(StackInspector.walkerHide);7778// Calls the StackInspector.create method through reflection79// and check the frames collected in the StackInspector80// default constructor.81// The create method invokes new StackInspector() directly.82// No reflection frame should appear.83System.out.println("testNewStackInspector: create");8485StackInspector obj = ((StackInspector)StackInspector.Caller.class86.getMethod("create", How.class)87.invoke(null, How.NEW));88assertEquals(obj.collectedFrames,89List.of(StackInspector.class.getName()90+"::<init>",91StackInspector.Caller.class.getName()92+"::create",93ReflectionFrames.class.getName()94+"::testNewStackInspector"));95assertEquals(obj.cls, StackInspector.Caller.class);96assertEquals(obj.filtered, 0);9798// Calls the StackInspector.reflect method through reflection99// and check the frames collected in the StackInspector100// default constructor.101// The reflect method invokes the create method through102// reflection.103// The create method invokes new StackInspector() directly.104// No reflection frame should appear.105System.out.println("testNewStackInspector: reflect");106107obj = ((StackInspector)StackInspector.Caller.class108.getMethod("reflect", How.class)109.invoke(null, How.NEW));110assertEquals(obj.collectedFrames,111List.of(StackInspector.class.getName()112+"::<init>",113StackInspector.Caller.class.getName()114+"::create",115StackInspector.Caller.class.getName()116+"::reflect",117ReflectionFrames.class.getName()118+"::testNewStackInspector"));119assertEquals(obj.cls, StackInspector.Caller.class);120assertEquals(obj.filtered, 0);121122// Calls the StackInspector.handle method through reflection123// and check the frames collected in the StackInspector124// default constructor.125// The handle method invokes the create method using126// a MethodHandle.127// The create method invokes new StackInspector() directly.128// No reflection frame should appear.129System.out.println("testNewStackInspector: handle");130131obj = ((StackInspector)StackInspector.Caller.class132.getMethod("handle", How.class)133.invoke(null, How.NEW));134assertEquals(obj.collectedFrames,135List.of(StackInspector.class.getName()136+"::<init>",137StackInspector.Caller.class.getName()138+"::create",139StackInspector.Caller.class.getName()140+"::handle",141ReflectionFrames.class.getName()142+"::testNewStackInspector"));143assertEquals(obj.cls, StackInspector.Caller.class);144assertEquals(obj.filtered, 0);145146// Sets a non-default walker configured to show147// reflection frames148StackInspector.walker.set(StackInspector.walkerShow);149150// Calls the StackInspector.create method through reflection151// and check the frames collected in the StackInspector152// default constructor.153// The create method invokes new StackInspector() directly.154// We should see all reflection frames, except the155// jdk.internal.reflect frames which we are filtering156// out in StackInspector::filter.157System.out.println("testNewStackInspector: create: show reflect");158159obj = ((StackInspector)StackInspector.Caller.class160.getMethod("create", How.class)161.invoke(null, How.NEW));162assertEquals(obj.collectedFrames,163List.of(StackInspector.class.getName()164+"::<init>",165StackInspector.Caller.class.getName()166+"::create",167Method.class.getName()168+"::invoke",169ReflectionFrames.class.getName()170+"::testNewStackInspector"));171assertEquals(obj.cls, StackInspector.Caller.class);172assertNotEquals(obj.filtered, 0);173174// Calls the StackInspector.reflect method through reflection175// and check the frames collected in the StackInspector176// default constructor.177// The reflect method invokes the create method through178// reflection.179// The create method invokes new StackInspector() directly.180// We should see all reflection frames, except the181// jdk.internal.reflect frames which we are filtering182// out in StackInspector::filter.183System.out.println("testNewStackInspector: reflect: show reflect");184185obj = ((StackInspector)StackInspector.Caller.class186.getMethod("reflect", How.class)187.invoke(null, How.NEW));188assertEquals(obj.collectedFrames,189List.of(StackInspector.class.getName()190+"::<init>",191StackInspector.Caller.class.getName()192+"::create",193Method.class.getName()194+"::invoke",195StackInspector.Caller.class.getName()196+"::reflect",197Method.class.getName()198+"::invoke",199ReflectionFrames.class.getName()200+"::testNewStackInspector"));201assertEquals(obj.cls, StackInspector.Caller.class);202assertNotEquals(obj.filtered, 0);203204// Calls the StackInspector.handle method through reflection205// and check the frames collected in the StackInspector206// default constructor.207// The handle method invokes the create method using208// MethodHandle.209// The create method invokes new StackInspector() directly.210// We should see all reflection frames, except the211// jdk.internal.reflect frames which we are filtering212// out in StackInspector::filter.213System.out.println("testNewStackInspector: handle: show reflect");214215obj = ((StackInspector)StackInspector.Caller.class216.getMethod("handle", How.class)217.invoke(null, How.NEW));218assertEquals(obj.collectedFrames,219List.of(StackInspector.class.getName()220+"::<init>",221StackInspector.Caller.class.getName()222+"::create",223// MethodHandle::invoke remains hidden224StackInspector.Caller.class.getName()225+"::handle",226Method.class.getName()227+"::invoke",228ReflectionFrames.class.getName()229+"::testNewStackInspector"));230assertEquals(obj.cls, StackInspector.Caller.class);231assertNotEquals(obj.filtered, 0);232}233234/**235* This test invokes Constructor.newInstance() from236* the caller StackInspector.Caller.create method.237* It checks that the caller is StackInspector.Caller.238* It also checks the expected frames collected239* by walking the stack from the default StackInspector()240* constructor.241* This is done twice, once using a default StackWalker242* that hides reflection frames, once using a StackWalker243* configured to show reflection frames.244*/245@Test246public static void testConstructor() throws Exception {247// Sets the default walker which hides reflection248// frames.249StackInspector.walker.set(StackInspector.walkerHide);250251// Calls the StackInspector.create method through reflection252// and check the frames collected in the StackInspector253// default constructor.254// The create method invokes Constructor.newInstance().255// No reflection frame should appear.256System.out.println("testConstructor: create");257258StackInspector obj = ((StackInspector)StackInspector.Caller.class259.getMethod("create", How.class)260.invoke(null, How.CONSTRUCTOR));261assertEquals(obj.collectedFrames,262List.of(StackInspector.class.getName()263+"::<init>",264StackInspector.Caller.class.getName()265+"::create",266ReflectionFrames.class.getName()267+"::testConstructor"));268assertEquals(obj.cls, StackInspector.Caller.class);269assertEquals(obj.filtered, 0);270271// Calls the StackInspector.reflect method through reflection272// and check the frames collected in the StackInspector273// default constructor.274// The reflect method invokes the create method through275// reflection.276// The create method invokes Constructor.newInstance().277// No reflection frame should appear.278System.out.println("testConstructor: reflect");279280obj = ((StackInspector)StackInspector.Caller.class281.getMethod("reflect", How.class)282.invoke(null, How.CONSTRUCTOR));283assertEquals(obj.collectedFrames,284List.of(StackInspector.class.getName()285+"::<init>",286StackInspector.Caller.class.getName()287+"::create",288StackInspector.Caller.class.getName()289+"::reflect",290ReflectionFrames.class.getName()291+"::testConstructor"));292assertEquals(obj.cls, StackInspector.Caller.class);293assertEquals(obj.filtered, 0);294295// Calls the StackInspector.handle method through reflection296// and check the frames collected in the StackInspector297// default constructor.298// The handle method invokes the create method using299// MethodHandle.300// The create method invokes Constructor.newInstance().301// No reflection frame should appear.302System.out.println("testConstructor: handle");303304obj = ((StackInspector)StackInspector.Caller.class305.getMethod("handle", How.class)306.invoke(null, How.CONSTRUCTOR));307assertEquals(obj.collectedFrames,308List.of(StackInspector.class.getName()309+"::<init>",310StackInspector.Caller.class.getName()311+"::create",312StackInspector.Caller.class.getName()313+"::handle",314ReflectionFrames.class.getName()315+"::testConstructor"));316assertEquals(obj.cls, StackInspector.Caller.class);317assertEquals(obj.filtered, 0);318319// Sets a non-default walker configured to show320// reflection frames321StackInspector.walker.set(StackInspector.walkerShow);322323// Calls the StackInspector.create method through reflection324// and check the frames collected in the StackInspector325// default constructor.326// The create method invokes Constructor.newInstance().327// We should see all reflection frames, except the328// jdk.internal.reflect frames which we are filtering329// out in StackInspector::filter.330System.out.println("testConstructor: create: show reflect");331332obj = ((StackInspector)StackInspector.Caller.class333.getMethod("create", How.class)334.invoke(null, How.CONSTRUCTOR));335assertEquals(obj.collectedFrames,336List.of(StackInspector.class.getName()337+"::<init>",338Constructor.class.getName()339+"::newInstanceWithCaller",340Constructor.class.getName()341+"::newInstance",342StackInspector.Caller.class.getName()343+"::create",344Method.class.getName()345+"::invoke",346ReflectionFrames.class.getName()347+"::testConstructor"));348assertEquals(obj.cls, StackInspector.Caller.class);349assertNotEquals(obj.filtered, 0);350351// Calls the StackInspector.reflect method through reflection352// and check the frames collected in the StackInspector353// default constructor.354// The reflect method invokes the create method through355// reflection.356// The create method invokes Constructor.newInstance().357// We should see all reflection frames, except the358// jdk.internal.reflect frames which we are filtering359// out in StackInspector::filter.360System.out.println("testConstructor: reflect: show reflect");361362obj = ((StackInspector)StackInspector.Caller.class363.getMethod("reflect", How.class)364.invoke(null, How.CONSTRUCTOR));365assertEquals(obj.collectedFrames,366List.of(StackInspector.class.getName()367+"::<init>",368Constructor.class.getName()369+"::newInstanceWithCaller",370Constructor.class.getName()371+"::newInstance",372StackInspector.Caller.class.getName()373+"::create",374Method.class.getName()375+"::invoke",376StackInspector.Caller.class.getName()377+"::reflect",378Method.class.getName()379+"::invoke",380ReflectionFrames.class.getName()381+"::testConstructor"));382assertEquals(obj.cls, StackInspector.Caller.class);383assertNotEquals(obj.filtered, 0);384385// Calls the StackInspector.handle method through reflection386// and check the frames collected in the StackInspector387// default constructor.388// The handle method invokes the create method using389// MethodHandle.390// The create method invokes Constructor.newInstance().391// We should see all reflection frames, except the392// jdk.internal.reflect frames which we are filtering393// out in StackInspector::filter.394System.out.println("testConstructor: handle: show reflect");395396obj = ((StackInspector)StackInspector.Caller.class397.getMethod("handle", How.class)398.invoke(null, How.CONSTRUCTOR));399assertEquals(obj.collectedFrames,400List.of(StackInspector.class.getName()401+"::<init>",402Constructor.class.getName()403+"::newInstanceWithCaller",404Constructor.class.getName()405+"::newInstance",406StackInspector.Caller.class.getName()407+"::create",408// MethodHandle::invoke remains hidden409StackInspector.Caller.class.getName()410+"::handle",411Method.class.getName()412+"::invoke",413ReflectionFrames.class.getName()414+"::testConstructor"));415assertEquals(obj.cls, StackInspector.Caller.class);416assertNotEquals(obj.filtered, 0);417}418419/**420* This test invokes StackInspector.class.newInstance() from421* the caller StackInspector.Caller.create method. Because422* Class.newInstance() is not considered as a423* reflection frame, the the caller returned by424* getCallerClass() should appear to be java.lang.Class425* and not StackInspector.Caller.426* It also checks the expected frames collected427* by walking the stack from the default StackInspector()428* constructor.429* This is done twice, once using a default StackWalker430* that hides reflection frames, once using a StackWalker431* configured to show reflection frames.432*/433@Test434public static void testNewInstance() throws Exception {435// Sets the default walker which hides reflection436// frames.437StackInspector.walker.set(StackInspector.walkerHide);438439// Calls the StackInspector.create method through reflection440// and check the frames collected in the StackInspector441// default constructor.442// The create method invokes StackInspector.class.newInstance().443// No reflection frame should appear, except444// Class::newInstance which is not considered as445// a reflection frame.446System.out.println("testNewInstance: create");447448StackInspector obj = ((StackInspector)StackInspector.Caller.class449.getMethod("create", How.class)450.invoke(null, How.CLASS));451assertEquals(obj.collectedFrames,452List.of(StackInspector.class.getName()453+"::<init>",454REFLECT_ACCESS.getName()455+"::newInstance",456REFLECTION_FACTORY.getName()457+"::newInstance",458Class.class.getName()459+"::newInstance",460StackInspector.Caller.class.getName()461+"::create",462ReflectionFrames.class.getName()463+"::testNewInstance"));464// Because implementation frames are not filtered, then the465// caller is ReflectAccess.class466assertEquals(obj.cls, REFLECT_ACCESS);467assertEquals(obj.filtered, 0);468469// Calls the StackInspector.reflect method through reflection470// and check the frames collected in the StackInspector471// default constructor.472// The reflect method invokes the create method through473// reflection.474// The create method invokes StackInspector.class.newInstance().475// No reflection frame should appear, except476// Class::newInstance which is not considered as477// a reflection frame.478System.out.println("testNewInstance: reflect");479480obj = ((StackInspector)StackInspector.Caller.class481.getMethod("reflect", How.class)482.invoke(null, How.CLASS));483assertEquals(obj.collectedFrames,484List.of(StackInspector.class.getName()485+"::<init>",486REFLECT_ACCESS.getName()487+"::newInstance",488REFLECTION_FACTORY.getName()489+"::newInstance",490Class.class.getName()491+"::newInstance",492StackInspector.Caller.class.getName()493+"::create",494StackInspector.Caller.class.getName()495+"::reflect",496ReflectionFrames.class.getName()497+"::testNewInstance"));498499// Because implementation frames are not filtered, then the500// caller is ReflectAccess.class501assertEquals(obj.cls, REFLECT_ACCESS);502assertEquals(obj.filtered, 0);503504// Calls the StackInspector.handle method through reflection505// and check the frames collected in the StackInspector506// default constructor.507// The handle method invokes the create method using508// reflection.509// The create method invokes StackInspector.class.newInstance().510// No reflection frame should appear, except511// Class::newInstance which is not considered as512// a reflection frame.513System.out.println("testNewInstance: handle");514515obj = ((StackInspector)StackInspector.Caller.class516.getMethod("handle", How.class)517.invoke(null, How.CLASS));518assertEquals(obj.collectedFrames,519List.of(StackInspector.class.getName()520+"::<init>",521REFLECT_ACCESS.getName()522+"::newInstance",523REFLECTION_FACTORY.getName()524+"::newInstance",525Class.class.getName()526+"::newInstance",527StackInspector.Caller.class.getName()528+"::create",529StackInspector.Caller.class.getName()530+"::handle",531ReflectionFrames.class.getName()532+"::testNewInstance"));533534// Because implementation frames are not filtered, then the535// caller is ReflectAccess.class536assertEquals(obj.cls, REFLECT_ACCESS);537assertEquals(obj.filtered, 0);538539// Sets a non-default walker configured to show540// reflection frames541StackInspector.walker.set(StackInspector.walkerShow);542543// Calls the StackInspector.create method through reflection544// and check the frames collected in the StackInspector545// default constructor.546// The create method invokes StackInspector.class.newInstance().547// We should see all reflection frames, except the548// jdk.internal.reflect frames which we are filtering549// out in StackInspector::filter.550System.out.println("testNewInstance: create: show reflect");551552obj = ((StackInspector)StackInspector.Caller.class553.getMethod("create", How.class)554.invoke(null, How.CLASS));555assertEquals(obj.collectedFrames,556List.of(StackInspector.class.getName()557+"::<init>",558Constructor.class.getName()559+"::newInstanceWithCaller",560REFLECT_ACCESS.getName()561+"::newInstance",562Class.class.getName()563+"::newInstance",564StackInspector.Caller.class.getName()565+"::create",566Method.class.getName()567+"::invoke",568ReflectionFrames.class.getName()569+"::testNewInstance"));570// Because implementation frames are not filtered, then the571// caller is ReflectAccess.class572assertEquals(obj.cls, REFLECT_ACCESS);573assertNotEquals(obj.filtered, 0);574575// Calls the StackInspector.reflect method through reflection576// and check the frames collected in the StackInspector577// default constructor.578// The reflect method invokes the create method through579// reflection.580// The create method invokes StackInspector.class.newInstance().581// We should see all reflection frames, except the582// jdk.internal.reflect frames which we are filtering583// out in StackInspector::filter.584System.out.println("testNewInstance: reflect: show reflect");585586obj = ((StackInspector)StackInspector.Caller.class587.getMethod("reflect", How.class)588.invoke(null, How.CLASS));589System.out.println(obj.collectedFrames);590assertEquals(obj.collectedFrames,591List.of(StackInspector.class.getName()592+"::<init>",593Constructor.class.getName()594+"::newInstanceWithCaller",595REFLECT_ACCESS.getName()596+"::newInstance",597Class.class.getName()598+"::newInstance",599StackInspector.Caller.class.getName()600+"::create",601Method.class.getName()602+"::invoke",603StackInspector.Caller.class.getName()604+"::reflect",605Method.class.getName()606+"::invoke",607ReflectionFrames.class.getName()608+"::testNewInstance"));609610// Because implementation frames are not filtered, then the611// caller is ReflectAccess.class612assertEquals(obj.cls, REFLECT_ACCESS);613assertNotEquals(obj.filtered, 0);614615// Calls the StackInspector.handle method through reflection616// and check the frames collected in the StackInspector617// default constructor.618// The handle method invokes the create method using619// MethodHandle.620// The create method invokes StackInspector.class.newInstance().621// We should see all reflection frames, except the622// jdk.internal.reflect frames which we are filtering623// out in StackInspector::filter.624System.out.println("testNewInstance: handle: show reflect");625626obj = ((StackInspector)StackInspector.Caller.class627.getMethod("handle", How.class)628.invoke(null, How.CLASS));629assertEquals(obj.collectedFrames,630List.of(StackInspector.class.getName()631+"::<init>",632Constructor.class.getName()633+"::newInstanceWithCaller",634REFLECT_ACCESS.getName()635+"::newInstance",636Class.class.getName()637+"::newInstance",638StackInspector.Caller.class.getName()639+"::create",640// MethodHandle::invoke remains hidden641StackInspector.Caller.class.getName()642+"::handle",643Method.class.getName()644+"::invoke",645ReflectionFrames.class.getName()646+"::testNewInstance"));647648// Because implementation frames are not filtered, then the649// caller is ReflectAccess.class650assertEquals(obj.cls, REFLECT_ACCESS);651assertNotEquals(obj.filtered, 0);652}653654@Test655public static void testGetCaller() throws Exception {656// Sets the default walker which hides reflection657// frames.658StackInspector.walker.set(StackInspector.walkerHide);659660assertEquals(StackInspector.getCaller(), ReflectionFrames.class);661assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),662ReflectionFrames.class);663664// Sets a non-default walker configured to show665// reflection frames666StackInspector.walker.set(StackInspector.walkerShow);667668assertEquals(StackInspector.getCaller(), ReflectionFrames.class);669assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),670ReflectionFrames.class);671}672673@Test674public static void testReflectCaller() throws Exception {675// Sets the default walker which hides reflection676// frames.677StackInspector.walker.set(StackInspector.walkerHide);678679assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);680assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),681ReflectionFrames.class);682683// Sets a non-default walker configured to show684// reflection frames685StackInspector.walker.set(StackInspector.walkerShow);686687assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);688assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),689ReflectionFrames.class);690}691692@Test693public static void testSupplyCaller() throws Exception {694// Sets the default walker which hides reflection695// frames.696StackInspector.walker.set(StackInspector.walkerHide);697698assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);699assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),700ReflectionFrames.class);701702// Sets a non-default walker configured to show703// reflection frames704StackInspector.walker.set(StackInspector.walkerShow);705706assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);707assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),708ReflectionFrames.class);709}710711@Test712public static void testHandleCaller() throws Exception {713// Sets the default walker which hides reflection714// frames.715StackInspector.walker.set(StackInspector.walkerHide);716717assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);718assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),719ReflectionFrames.class);720721// Sets a non-default walker configured to show722// reflection frames723StackInspector.walker.set(StackInspector.walkerShow);724725assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);726assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),727ReflectionFrames.class);728}729730static enum How { NEW, CONSTRUCTOR, CLASS};731732/**733* An object that collect stack frames by walking the stack734* (and calling getCallerClass()) from within its constructor.735* For the purpose of this test, StackInspector objects are736* always created from the nested StackInspector.Caller class,737* which should therefore appear as the caller of the738* StackInspector constructor.739*/740static class StackInspector {741static final StackWalker walkerHide =742StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);743static final StackWalker walkerShow =744StackWalker.getInstance(EnumSet.of(745StackWalker.Option.RETAIN_CLASS_REFERENCE,746StackWalker.Option.SHOW_REFLECT_FRAMES));747final static ThreadLocal<StackWalker> walker = new ThreadLocal<>() {748protected StackWalker initialValue() {749return walkerHide;750}751};752753List<String> collectedFrames;754Class<?> cls = null;755boolean stop;756int filtered;757final boolean filterImplFrames;758759public StackInspector() {760stop = false;761// if reflection frames are not hidden, we want to762// filter implementation frames before collecting763// to avoid depending on internal details.764filterImplFrames = walker.get() == walkerShow;765collectedFrames = walker.get().walk(this::parse);766cls = walker.get().getCallerClass();767}768769public List<String> collectedFrames() {770return collectedFrames;771}772773// The takeWhile method arrange for stopping frame collection774// as soon as a frame from ReflectionFrames.class is reached.775// The first such frame encountered is still included in the776// collected frames, but collection stops right after.777// This makes it possible to filter out anything above the778// the test method frame, such as frames from the test779// framework.780public boolean takeWhile(StackFrame f) {781if (stop) return false;782if (verbose) System.out.println(" " + f);783stop = stop || f.getDeclaringClass() == ReflectionFrames.class;784return true;785}786787// filter out implementation frames to avoid depending788// on implementation details. If present, Class::newInstance,789// Method::invoke and Constructor::newInstance will790// still appear in the collected frames, which is791// sufficient for the purpose of the test.792// In the case where the StackWalker itself is supposed to793// filter the reflection frames, then this filter will always794// return true. This way, if such a reflection frame appears when795// it sjould have been filtered by StackWalker, it will make the796// test fail.797public boolean filter(StackFrame f) {798if (filterImplFrames &&799f.getClassName().startsWith("jdk.internal.reflect.")) {800filtered++;801return false;802}803if (!verbose) System.out.println(" " + f);804return true;805}806807public String frame(StackFrame f) {808return f.getClassName() + "::" + f.getMethodName();809}810811List<String> parse(Stream<StackFrame> s) {812return s.takeWhile(this::takeWhile)813.filter(this::filter)814.map(this::frame)815.collect(Collectors.toList());816}817818/**819* The Caller class is used to create instances of820* StackInspector, either direcltly, or throug reflection.821*/822public static class Caller {823public static StackInspector create(How how) throws Exception {824switch(how) {825case NEW: return new StackInspector();826case CONSTRUCTOR: return StackInspector.class827.getConstructor().newInstance();828case CLASS: return StackInspector.class.newInstance();829default: throw new AssertionError(String.valueOf(how));830}831}832public static StackInspector reflect(How how) throws Exception {833return (StackInspector) Caller.class.getMethod("create", How.class)834.invoke(null, how);835}836public static StackInspector handle(How how) throws Exception {837Lookup lookup = MethodHandles.lookup();838MethodHandle mh = lookup.findStatic(Caller.class, "create",839MethodType.methodType(StackInspector.class, How.class));840try {841return (StackInspector) mh.invoke(how);842} catch (Error | Exception x) {843throw x;844} catch(Throwable t) {845throw new AssertionError(t);846}847}848}849850public static Class<?> getCaller() throws Exception {851return walker.get().getCallerClass();852}853854public static Class<?> reflectCaller() throws Exception {855return (Class<?>)StackWalker.class.getMethod("getCallerClass")856.invoke(walker.get());857}858859public static Class<?> supplyCaller() throws Exception {860return ((Supplier<Class<?>>)StackInspector.walker.get()::getCallerClass).get();861}862863public static Class<?> handleCaller() throws Exception {864Lookup lookup = MethodHandles.lookup();865MethodHandle mh = lookup.findVirtual(StackWalker.class, "getCallerClass",866MethodType.methodType(Class.class));867try {868return (Class<?>) mh.invoke(walker.get());869} catch (Error | Exception x) {870throw x;871} catch(Throwable t) {872throw new AssertionError(t);873}874}875}876}877878879