/src/java.base/share/classes/jdk/internal/reflect/CallerSensitiveAdapter.java

https://github.com/openjdk/valhalla · Java · 112 lines · 9 code · 4 blank · 99 comment · 0 complexity · 5dbfd0585503bcf1052fcdd868897897 MD5 · raw file

  1. /*
  2. * Copyright (c) 2021, 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. Oracle designates this
  8. * particular file as subject to the "Classpath" exception as provided
  9. * by Oracle in the LICENSE file that accompanied this code.
  10. *
  11. * This code is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. * version 2 for more details (a copy is included in the LICENSE file that
  15. * accompanied this code).
  16. *
  17. * You should have received a copy of the GNU General Public License version
  18. * 2 along with this work; if not, write to the Free Software Foundation,
  19. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22. * or visit www.oracle.com if you need additional information or have any
  23. * questions.
  24. */
  25. package jdk.internal.reflect;
  26. import java.lang.annotation.Retention;
  27. import java.lang.annotation.RetentionPolicy;
  28. import java.lang.annotation.Target;
  29. import static java.lang.annotation.ElementType.METHOD;
  30. /**
  31. * A method annotated @CallerSensitiveAdapter is an adapter method corresponding
  32. * to a caller-sensitive method, which is annotated with @CallerSensitive.
  33. *
  34. * A caller-sensitive adapter is private and has the same name as its
  35. * corresponding caller-sensitive method with a trailing caller class parameter.
  36. *
  37. * When a caller-sensitive method is invoked via Method::invoke or MethodHandle
  38. * the core reflection and method handle implementation will find if
  39. * an @CallerSensitiveAdapter method for that CSM is present. If present,
  40. * the runtime will invoke the adapter method with the caller class
  41. * argument instead. This special calling sequence ensures that the same caller
  42. * class is passed to a caller-sensitive method via Method::invoke,
  43. * MethodHandle::invokeExact, or a mix of these methods.
  44. *
  45. * For example, CSM::returnCallerClass is a caller-sensitive method
  46. * with an adapter method:
  47. * {@code
  48. * class CSM {
  49. * @CallerSensitive
  50. * static Class<?> returnCallerClass() {
  51. * return returnCallerClass(Reflection.getCallerClass());
  52. * }
  53. * @CallerSensitiveAdapter
  54. * private static Class<?> returnCallerClass(Class<?> caller) {
  55. * return caller;
  56. * }
  57. * }
  58. *
  59. * class Test {
  60. * void test() throws Throwable {
  61. * // calling CSM::returnCallerClass via reflection
  62. * var csm = CSM.class.getMethod("returnCallerClass");
  63. * // expect Foo to be the caller class
  64. * var caller = csm.invoke(null);
  65. * assert(caller == Test.class);
  66. * }
  67. * void test2() throws Throwable {
  68. * // method handle for Method::invoke
  69. * MethodHandle mh = MethodHandles.lookup().findVirtual(Method.class, "invoke",
  70. * methodType(Object.class, Object.class, Object[].class));
  71. * var csm = CSM.class.getMethod("returnCallerClass");
  72. * // invoke Method::invoke via method handle and the target method
  73. * // being invoked reflectively is CSM::returnCallerClass
  74. * var caller = mh.invoke(csm, null, null);
  75. * assert(caller == Test.class);
  76. * }
  77. * }
  78. * }
  79. *
  80. *
  81. * Both CSM::returnCallerClass and Method::invoke can have an adapter method
  82. * with a caller-class parameter defined. Test::test calls CSM::returnCallerClass
  83. * via Method::invoke which does the stack walking to find the caller's class.
  84. * It will pass the caller's class directly to the adapter method for
  85. * CSM::returnCallerClass.
  86. *
  87. * Similarly, Test::test2 invokes the method handle of Method::invoke to
  88. * call CSM::returnCallerClass reflectively. In that case, MethodHandle::invokeExact
  89. * uses the lookup class of the Lookup object producing the method handle
  90. * as the caller's class, so no stack walking involved. The lookup class is Test.
  91. * It will invoke the adapter method of Method::invoke with Test as the caller's
  92. * class, which in turn invokes the adapter method of CSM::returnCallerClass
  93. * with Test as the caller. The calling sequence eliminates the need for
  94. * multiple stack walks when a caller-sensitive method is invoked reflectively.
  95. *
  96. * For caller-sensitive methods that require an exact caller class, the adapter
  97. * method must be defined for correctness. {@link java.lang.invoke.MethodHandles#lookup()}
  98. * and {@link ClassLoader#registerAsParallelCapable()} are the only two methods
  99. * in the JDK that need the exact caller class.
  100. *
  101. * On the other hand, for caller-sensitive methods that use the caller's class
  102. * for access checks or security permission checks, i.e., based on its runtime
  103. * package, defining loader, or protection domain, the adapter method is optional.
  104. */
  105. @Retention(RetentionPolicy.CLASS)
  106. @Target({METHOD})
  107. public @interface CallerSensitiveAdapter {
  108. }