On Tue, Jul 30, 2013 at 7:17 AM, Peter Levart <peter.lev...@gmail.com> wrote: > For outside JDK use, I think there are two main needs, which are actually > distinct: > > a) the caller-sensitive methods > b) anything else that is not caller-sensitive, but wants to fiddle with the > call-stack > > For caller-sensitive methods, the approach taken with new > Reflection.getCallerClass() is the right one, I think. There's no need to > support a fragile API when caller-sensitivity is concerned, so the lack of > "int" parameter, combined with annotation for marking such methods is > correct approach, I think. The refactorings to support this change in JDK > show that this API is adequate. The "surface" public API methods must > capture the caller class and pass it down the internal API where it can be > used.
This is largely what I advocated and what we do in JRuby. First of all, we've never made any guarantees about calls to caller-sensitive methods like Class.forName. If issues were reported, our answer was to pass in a classloader, just as you would have to do if you had a utility library between your user code and a Class.forName call. Second, the presence of a hidden API to walk the stack is not an excuse for using it and then complaining when it is taken away. Yes yes, Unsafe falls into this category too, but in the case of Unsafe there's no alternative. With getCallerClass, there is an alternative: pass down the caller class. This may not be attractive, especially given the magic provided by getCallerClass before...but it is a solution. Third, for language runtimes like Groovy, it seems to me that only *effort* is required to handle the passing down of the caller class. If we look at the facts, we see that getCallerClass is needed to skip intermediate frames by the runtime. So the runtime knows about these intermediate frames and knows how many to skip. This means that the original call is not into an uncontrolled library, but instead is into Groovy-controlled code. Passing down the caller object or class at that point is obviously possible. Even if the hassle of passing a new additional parameter through the call protocol is too difficult, a ThreadLocal could be utilized for this purpose. For the logging frameworks, I do not have a solution other than the same one we recommend to JRuby users: pass in the class or classloader. I could also suggest generating a backtrace and walking back to the appropriate element, but backtrace generation is currently far too expensive to use in heavily-hit logging code (this should be improved). I will also say that I agree an official stack-walking capability would be incredibly useful, and not just for this case. But that's a much bigger fish to fry and it won't happen in JDK8 timeframe. > Now that is the question for mlvm-dev mailing list: Isn't preventing almost > all Lookup objects obtained by Lookup.in(RequestedLookupClass.class) from > obtaining MHs of @CallerSensitive methods too restrictive? Probably. It seems to me that @CallerSensitive is no different from exposing private methods or fields through a MH. Perhaps it should recalculate caller when it's called, perhaps it should calculate it at lookup time, but not being retrievable at all seems like overkill. I will grant that overkill was probably the quickest and safest solution at the time. > I would point out that this could all easily be solved simply by adding a > getElementClass() method to StackTraceElement, but there was strong > opposition to this, largely due to serialization issues. Since that is > apparently not an option, I propose the following API, based on the various > discussions in the last two months, StackTraceElement, and the API that .NET > provides to achieve the same needs as listed above: A new stack trace getter that provides classes would be an immense improvement, but only if it did not have the same overhead as current stack trace generation. Again, that needs to be fixed. > Furthermore, I propose that we restore the behavior of > sun.reflect.Reflection#getCallerClass(int) /just for Java 7/ since the > proposed above solution cannot be added to Java 7. Probably for 7 and 8. I'm pessimistic about its use, but the timeframe for moving away from it is too short. - Charlie _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev