Classes on the stack trace (was: getElementClass/StackTraceElement, was: @CallerSensitive public API, was: sun.reflect.Reflection.getCallerClass)
peter.levart at gmail.com
Tue Jul 30 14:16:45 UTC 2013
On 07/30/2013 03:19 PM, Jochen Theodorou wrote:
> Am 30.07.2013 14:17, schrieb Peter Levart:
>> So what would give Groovy or other language runtimes headaches when all
>> there was was a parameter-less getCallerClass() API? Aren't the
>> intermediate frames inserted by those runtimes controlled by the
>> runtimes? Couldn't the "surface" runtime-inserted methods capture the
>> caller and pass it down? I guess the problem is supporting calling the
>> caller-sensitive methods like Class.forName(String) and such which don't
>> have the overloaded variant taking caller Class or ClassLoader as an
> Speaking for Groovy...
> those intermediate frames are runtime controlled, yes, but passing down
> the caller class is exactly the problem. Imagine I would suggest that
> each and every method definition in Java automatically gets an
> additional parameter for the caller class, just to have access to it
> inside the method. You would not accept that for Java, would you? And so
> we cannot accept that for Groovy if we want to keep integration with
Are you talking about internal Groovy implementation (the
runtime-inserted methods) or the publicly visible API? One solution for
internal implementation of Groovy could be (speaking by heart since I
don't know the internals of Groovy) for the "surface" public API method
which doesn't have to have the special caller parameter, to capture the
caller with getCallerClass() parameterless API (possibly enclosed with a
quick check confirming that it might actually be needed) and bind it to
a ThreadLocal, then use this ThreadLocal down at the end...
> and the good integration with Java is one of the key points of
> Groovy. Even if we make something like that @CallerSensitive and add the
> parameter only in those cases, we break being able to override methods.
I guess I don't know every Groovy need to obtain the caller class. I
thought the problem was to support calling caller-sensitive methods in
Java API (like Class.forName(String)) from within Groovy code, where
there are runtime-inserted frames between the "call-site" and the target
method. Are there any other needs?
> Plus, before Groovy3 is not done we have to support several call paths.
> And the oldest one, which is still a fallback, does not support
> transporting the caller class through the runtime layers at all.
> Changing here is a breaking change.
Could you describe those call-paths? Examples of Groovy code and to what
it gets translated (equivalent Java code at call site) with a brief
description of what each intermediate layer (between the call-site and
the target method) does and at which point the caller class is extracted...
>> John Rose suggested to "capture" the caller in the "surface" method and
>> bind it with a MethodHandle and then pass such MH down the runtime API
>> and finally call that method via MH.
> Only that you then need a java7+ only version, plus the already
> mentioned problem, that not all of the three general call paths support
> that or can be changed in a way to enable that without breaking user code.
> bye Jochen
More information about the core-libs-dev