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