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.





Sent from Mail for Windows 10



From: David M. Lloyd
Sent: Saturday, November 14, 2015 16:02
To: core-libs-dev@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.

-- 
- DML


Reply via email to