Proposed API for JEP 259: Stack-Walking API

Peter Levart peter.levart at gmail.com
Wed Nov 4 08:21:40 UTC 2015



On 11/04/2015 09:06 AM, Peter Levart wrote:
>>> What would it be if getCallerClass() returned just 
>>> Optional<Class<?>> and was left to the user to decide what to do in 
>>> corner cases when there is no Java caller?
>>>
>> 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.
>
> I was not thinking of calling StackWalker::getCallerClass from native, 
> but calling some method from native, which then calls 
> StackWalker::getCallerClass. The method itself can not anticipate how 
> it will be called. Most methods calling getCallerClass will assume 
> their caller is a Java method and won't bother to think of 
> consequences when this is not the case. But any method can be called 
> from native code in a newly attached thread. I'm not saying this is 
> common, but can happen.
>
> So the question is whether Thread.class is always the right substitute 
> in such situations and whether it would be better to return null or 
> Optional.empty(). If you don't want to force users to handle the 
> uncommon case then perhaps it's best to return null. They will get NPE 
> in the uncommon case and will be forced to handle it as opposed to 
> using Thread.class which might silently "work", but not do the right 
> thing. 

... additionaly, Thread.class (or a subclass) can not be reliably used 
as a sentinel value to identify such uncommon cases because it can 
sometimes be a legal caller, as in:

public class StackWalkerDemo {

     public static void doIt() {
         StackWalker sw = new 
StackWalker(StackWalker.Option.CLASS_REFERENCE);
         System.out.println("I was called from: " + sw.getCallerClass());
     }

     public static void main(String[] args) throws Exception {
         Thread t = new Thread(StackWalkerDemo::doIt);
         t.start();
         t.join();
     }
}


Regards, Peter




More information about the core-libs-dev mailing list