--- /dev/null 2016-07-13 18:11:35.000000000 +0800 +++ new/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/jdk/test/CallerSensitiveTest.java 2016-07-13 18:11:35.000000000 +0800 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.CSM.Result; +import java.util.function.Supplier; + +public class CallerSensitiveTest { + public static void main(String... args) throws Throwable { + boolean sm = false; + if (args.length > 0 && args[0].equals("sm")) { + sm = true; + PermissionCollection perms = new Permissions(); + perms.add(new StackFramePermission("retainClassReference")); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission p) { + return perms.implies(p); + } + }); + System.setSecurityManager(new SecurityManager()); + } + + System.err.format("Test %s security manager.%n", + sm ? "with" : "without"); + + CallerSensitiveTest cstest = new CallerSensitiveTest(); + // test static call to java.util.CSM::caller and CSM::getCallerClass + cstest.staticMethodCall(); + // test java.lang.reflect.Method call + cstest.reflectMethodCall(); + // test java.lang.invoke.MethodHandle + cstest.invokeMethodHandle(Lookup1.lookup); + cstest.invokeMethodHandle(Lookup2.lookup); + // test method ref + cstest.lambda(); + + LambdaTest.lambda(); + + + if (failed > 0) { + throw new RuntimeException(failed + " test cases failed."); + } + } + + void staticMethodCall() { + Result result1 = java.util.CSM.caller(); + checkCallerSensitiveCaller(result1); + + Result result2 = java.util.CSM.getCallerClass(); + checkNonCSMCaller(CallerSensitiveTest.class, result2); + } + + void reflectMethodCall() throws Throwable { + Method method1 = java.util.CSM.class.getMethod("caller"); + Result result1 = (Result) method1.invoke(null); + checkCallerSensitiveCaller(result1); + + Method method2 = java.util.CSM.class.getMethod("getCallerClass"); + Result result2 = (Result) method2.invoke(null); + checkNonCSMCaller(CallerSensitiveTest.class, result2); + } + + void invokeMethodHandle(Lookup lookup) throws Throwable { + MethodHandle mh1 = lookup.findStatic(java.util.CSM.class, "caller", + MethodType.methodType(Result.class)); + Result result1 = (Result)mh1.invokeExact(); + checkCallerSensitiveCaller(result1); + + MethodHandle mh2 = lookup.findStatic(java.util.CSM.class, "getCallerClass", + MethodType.methodType(Result.class)); + Result result2 = (Result)mh2.invokeExact(); + checkNonCSMCaller(CallerSensitiveTest.class, result2); + } + + void lambda() { + Result result1 = LambdaTest.caller.get(); + checkCallerSensitiveCaller(result1); + + Result result2 = LambdaTest.getCallerClass.get(); + checkNonCSMCaller(CallerSensitiveTest.class, result2); + } + + static int failed = 0; + + static void checkNonCSMCaller(Class expected, Result result) { + if (result.callers.size() != 1) { + throw new RuntimeException("Expected result.callers contain one element"); + } + if (expected != result.callers.get(0)) { + System.err.format("ERROR: Expected %s but got %s%n", expected, + result.callers); + result.frames.stream() + .forEach(f -> System.err.println(" " + f)); + failed++; + } + } + + static void checkCallerSensitiveCaller(Result result) { + Class expected = result.callers.get(0); + + if (expected != result.callers.get(0) || expected != result.callers.get(1)) { + System.err.format("ERROR: Expected %s but got %s%n", expected, + result.callers); + result.frames.stream() + .forEach(f -> System.err.println(" " + f)); + failed++; + } + } + + static class Lookup1 { + static Lookup lookup = MethodHandles.lookup(); + } + + static class Lookup2 { + static Lookup lookup = MethodHandles.lookup(); + } + + static class LambdaTest { + static Supplier caller = java.util.CSM::caller; + static Supplier getCallerClass = java.util.CSM::getCallerClass; + + static Result caller() { + return caller.get(); + } + static Result getCallerClass() { + return getCallerClass.get(); + } + + static void lambda() { + Result result1 = LambdaTest.caller(); + Result result2 = LambdaTest.getCallerClass(); + + checkCallerSensitiveCaller(result1); + checkNonCSMCaller(LambdaTest.class, result2); + } + } +}