On Jun 25, 2013, at 5:50 AM, Peter Levart wrote: > Hi, > > I know that @CallerSensitive annotation was introduced to bring some order to > JDK internal plumbings. It's scope was to support JDK internal usage, so it's > use is limited to classes loaded by bootstrap or extension class-loaders. In > JDK-internal code it is used mainly for implementing security-sensitive > decisions. But since the sun.reflect.Reflection.getCallerClass(int) was > public and unrestricted, it found it's way out into user code, where at least > I know that it is used in two areas: > > 1 - to locate callers in the whole call-stack so that their location in > class-path can be reported (Log4J is an example) > 2 - to locate immediate caller so that some resources associated with it can > be located and used (for example localization data in GUI applications) > > I don't know how wide-spread 1st usecase is, but the 2nd is common, since > it's use enables APIs that need not explicitly pass-in the calling class in > order to locate resources associated with it (and/or the class-loader of it). > So it would be nice to have such supported API in JDK8 at least. > > I'm asking here, to hear any arguments against making such API supported and > public. Are there any security or other issues? If there aren't, what steps > should be taken to introduce such API in the JDK8 timeframe? I'm thinking of > a no-arg method, say j.l.Class.getCaller() and moving @CallerSensitive to a > supported package + enabling it to mark methods in any class (not just system > and ext classes)... > > Regards, Peter
I'm all for making this API public, and I can see many uses and advantages to doing so. I would point out, however, that #1 actually has two parts: 1.A - To identify callers (Class<?>, not just name) in the _current_ call stack (currently supported, albeit in a difficult-to-use way, using Class<?>[] SecurityManager#getClassContext()). 1.B - To identify frames (Class<?>, not just name) in the stack generated _when throwing an exception_ (not currently supported at all). For those of us working on Log4j, #1.B is the biggest priority by orders of magnitude over #1.A and #2. See the existing discussion [1] for more info. I think the current most-viable options on the table (which some people had concerns about) were A) add the Class<?> to StackTraceElement and B) add a StackFrame class and add a StackFrame[] getStackFrames method to Throwable (similar to StackTraceElement[] getStackTrace()). StackFrame would contain Class<?> getFrameClass(), Executable getExecutable(), String getFileName(), int getLineNumber(), and boolean isNative(). As for #2, I would say this: @CallerSensitive is awesome; however, you can't annotate a class @CallerSensitive and it be runnable on Java 6. As much as it sucks, major projects like Log4j will have to support Java 6 for at least another 4-5 years. However, you _can_ conditionally use a Java 8 API and the code still be runnable on Java 6 (as long as there's backup code that executes in the absence of this API). So I would ask that there be a getCallerClass or equivalent method that works with an int skipFrames parameter (like now) or returns a Class<?>[] _in addition to_ a no-arg getCallerClass method that uses @CallerSensitive. My $0.02. Nick [1] http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-June/018049.html