Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8020968

Provide a replacement for sun.reflect.Reflection.getCallerClass

    Details

    • Type: Enhancement
    • Status: Closed
    • Priority: P2
    • Resolution: Duplicate
    • Affects Version/s: 8
    • Fix Version/s: 9
    • Component/s: core-libs
    • Labels:

      Description

      Class.getResource and ClassLoader.getResource are the APIs to obtain resource files associated with the class and/or classloader. An example in the JDK: ResourceBundle.getBundle finds the caller's class and uses the caller class loader to load a resource bundle. Libraries and frameworks such as Groovy, Log4j need similar capability and also need the ability to filter their implementation classes. Existing code has been using sun.reflect.Reflection.getCallerClass(int depth).

      There is no current way for libraries to support loading resource files on behalf of its immediate caller without explicitly passing the calling Class (for example localization data in GUI applications). See discussion in [1].

      [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/018353.html

        Issue Links

          Activity

          Hide
          mchung Mandy Chung added a comment -
          Existing frameworks have been using sun.reflect.Reflection.getCallerClass(int depth) to find the caller's class but it has been removed in jdk8 for JEP-176.

          JDK8 has to provide a replacement to support the use cases.
          Show
          mchung Mandy Chung added a comment - Existing frameworks have been using sun.reflect.Reflection.getCallerClass(int depth) to find the caller's class but it has been removed in jdk8 for JEP-176. JDK8 has to provide a replacement to support the use cases.
          Hide
          jrose John Rose added a comment -
          Here's a JDK 8 motivation for doing a better job of filtering and controlling backtrace displays:

          http://www.takipiblog.com/2014/03/25/the-dark-side-of-lambda-expressions-in-java-8/

          The gist of it is as we add more fancy language features on top of the JVM, there are more noisy internal frames in backtraces. This information is sometimes necessary, but it usually complicates the diagnosis of errors in the field.
          Show
          jrose John Rose added a comment - Here's a JDK 8 motivation for doing a better job of filtering and controlling backtrace displays: http://www.takipiblog.com/2014/03/25/the-dark-side-of-lambda-expressions-in-java-8/ The gist of it is as we add more fancy language features on top of the JVM, there are more noisy internal frames in backtraces. This information is sometimes necessary, but it usually complicates the diagnosis of errors in the field.
          Hide
          jrose John Rose added a comment -
          Tail call elimination requires a special kind of stack frame that saves stack-walk information that would otherwise be lost. Java's security model requires this. See discussion of "continuation marks" in http://mail.openjdk.java.net/pipermail/mlvm-dev/2013-July/005417.html and https://wiki.openjdk.java.net/display/mlvm/TailCalls#TailCalls-Stackwalkingandframeelision .
          Show
          jrose John Rose added a comment - Tail call elimination requires a special kind of stack frame that saves stack-walk information that would otherwise be lost. Java's security model requires this. See discussion of "continuation marks" in http://mail.openjdk.java.net/pipermail/mlvm-dev/2013-July/005417.html and https://wiki.openjdk.java.net/display/mlvm/TailCalls#TailCalls-Stackwalkingandframeelision .
          Hide
          jrose John Rose added a comment -
          The best way to replace getCallerClass, in my opinion, would be to link caller-sensitive methods in such a way that the JVM adds the caller class as an extra argument:

              Foo { void bar() {
                Class.forName("Baz"); // links as Class.forName(_, Foo.class)
              } }

              class Class { static native @CallerSensitive Class forName(String x); // stub
                private static Class forName(String x, @CallerSensitive Class caller) { // target used by JVM
                   ...do privileged stuff here...
                }
              }

          Note that the "real" entry point is private, so there is no way to spoof the API.

          The VM's link resolver is responsible for appending the extra argument.

          The existing "appendix" mechanism in the HotSpot JVM could be repurposed to perform this on-the-fly transformation.
          Show
          jrose John Rose added a comment - The best way to replace getCallerClass, in my opinion, would be to link caller-sensitive methods in such a way that the JVM adds the caller class as an extra argument:     Foo { void bar() {       Class.forName("Baz"); // links as Class.forName(_, Foo.class)     } }     class Class { static native @CallerSensitive Class forName(String x); // stub       private static Class forName(String x, @CallerSensitive Class caller) { // target used by JVM          ...do privileged stuff here...       }     } Note that the "real" entry point is private, so there is no way to spoof the API. The VM's link resolver is responsible for appending the extra argument. The existing "appendix" mechanism in the HotSpot JVM could be repurposed to perform this on-the-fly transformation.
          Hide
          mullan Sean Mullan added a comment -
          There are some caller-sensitive methods that only call Reflection.getCallerClass under certain conditions (ex: if a SecurityManager is enabled). Could we somehow distinguish those cases or do you think always attaching the caller class would not affect performance too much?
          Show
          mullan Sean Mullan added a comment - There are some caller-sensitive methods that only call Reflection.getCallerClass under certain conditions (ex: if a SecurityManager is enabled). Could we somehow distinguish those cases or do you think always attaching the caller class would not affect performance too much?
          Hide
          mchung Mandy Chung added a comment - - edited
          As specified in JEP 259 [1], StackWalker::getCallerClass and StackWalker::walk provide the replacement for sun.reflect.Reflection.getCallerClass. This issue is closed as a duplicate of JDK-8140450 (the implementation for JEP 259).

          [1] http://openjdk.java.net/jeps/259
          Show
          mchung Mandy Chung added a comment - - edited As specified in JEP 259 [1], StackWalker::getCallerClass and StackWalker::walk provide the replacement for sun.reflect.Reflection.getCallerClass. This issue is closed as a duplicate of JDK-8140450 (the implementation for JEP 259). [1] http://openjdk.java.net/jeps/259

            People

            • Assignee:
              mchung Mandy Chung
              Reporter:
              mchung Mandy Chung
            • Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: