Proposed API for JEP 259: Stack-Walking API

Peter Levart peter.levart at gmail.com
Sun Nov 15 19:15:29 UTC 2015



On 11/15/2015 05:53 PM, Timo Kinnunen wrote:
> To be pedantic, there is always a caller, but not every caller is associated with a Java Class.
>
> StackWalker::getCallerClass can be thought as a convenience method for something like:
> 	Class<?> callingMe = StackWalker.getCaller().getAsJavaClass();
>
>  From this view-point we can determine that
> • getCaller() will never return null as there is always a caller.
> • getAsJavaClass() cannot always return a Class instance as the caller might be the OS itself or a native code frame.
> • getCaller() will not return the current frame as the caller of the current frame because that’s nonsensical!
> • Also, getAsJavaClass() will not return a Java Class from some other caller as that would violate its API contract.
> • getAsJavaClass() will not return the current frame’s Class as the caller’s Class unless such a recursive call is actually in progress!
>
> We can guess that the client using these methods should have some idea if it’s expected its caller is a Java Class or not. We also know the association between a caller and a Java Class (if any) won’t change unexpectedly or otherwise have some uncertainty. Together these give the following API for getCaller() and getAsJavaClass():
>
> getCaller() always succeeds and returns non-null. The result is not guaranteed to contain information useful to clients. It returns the same caller regardless of who the callers of the caller are.
> getAsJavaClass() doesn’t always succeed, and when it does is dependent on local information only. When it doesn’t, it throws an exception to signal that the association to a Class that the client expected to find doesn’t exists. The exception is not a checked exception because the association between a caller and a Class is not inherently unreliable.
>
> The same reasoning applies to StackWalker::getCallerClass and further suggests StackWalker::getCaller should be available for clients as well.

But what would  StackWalker::getCaller actually return? If it is an 
object that contains just getAsJavaClas() method, then it is a useless 
indirection (similar to Optional<Class<?>>).

Since the situation that a "caller-sensitive" method is not called by a 
Java method is really just a theoretical issue and even then it is an 
abuse made by the caller of a caller-sensitive method, I would just make 
getCallerClass() throw an exception in such situations.

Regards, Peter

>
>
>
>
> Sent from Mail for Windows 10
>
>
>
> From: David M. Lloyd
> Sent: Saturday, November 14, 2015 16:02
> To: core-libs-dev at openjdk.java.net
> Subject: Re: Proposed API for JEP 259: Stack-Walking API
>
>
> On 11/13/2015 06:07 PM, Brian Goetz wrote:
>>> I considered Optional<Class<?>>. I believe it is rare to have a JNI
>>> attached thread calling StackWalker::getCallerClass from native.  Most
>>> common cases will find a caller class.   Returning an Optional will
>>> force most common uses to handle the case if it’s absent.  It’s a
>>> tradeoff that I think it’s better to return Thread.class for the JNI
>>> attached thread calling getCallerClass in native which would rarely
>>> happen.
>> +1 on returning Thread.class in these cases.  Its a pragmatic compromise.
> If you must return something non-null, maybe it'd be better to define a
> class just for that purpose, e.g.:
>
> public final class StackWalker {
>
>       ...
>
>       public static final class NoCaller {
>           private NoCaller() {}
>       }
> }
>
> ...and use NoCaller.class as your caller when there is none.  Bonus
> points if you can attach a protection domain with no permissions to that
> class.
>




More information about the core-libs-dev mailing list