Proposed API for JEP 259: Stack-Walking API

Mandy Chung mandy.chung at oracle.com
Mon Nov 16 19:25:10 UTC 2015


StackWalker::getCallerClass is intended to find 2 frames below it and for a specific purpose.  For anything else, you can build on top of StackWalker::walk easily.  It doesn’t eagerly dump the entire stack and walk the stack one batch at a time.

Mandy

> On Nov 15, 2015, at 1:37 PM, Timo Kinnunen <timo.kinnunen at gmail.com> wrote:
> 
> I hope StackWalker::getCaller would return at least as much information as invoking the MBean operation { “threadPrint”, “–l” } from com.sun.management.DiagnosticCommand directly would get, without the overheads of a full thread dump. I also noticed that many users of the original getCallerClass() are not really interested in the caller’s Class per se, rather they are interested in the caller’s ClassLoader. StackWalker::getCaller could then also include this information and other details about the calling context in effect at the time it is called.
> 
> 
> 
> Sent from Mail for Windows 10
> 
> 
> 
> From: Peter Levart
> Sent: Sunday, November 15, 2015 20:15
> To: Timo Kinnunen;David M. Lloyd;core-libs-dev at openjdk.java.net
> Subject: Re: Proposed API for JEP 259: Stack-Walking API
> 
> 
> 
> 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