/* * 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); } } }