Proposed API for JEP 259: Stack-Walking API
Peter Levart
peter.levart at gmail.com
Tue Nov 3 14:31:58 UTC 2015
On 11/03/2015 02:20 PM, Daniel Fuchs wrote:
> Hi Peter,
>
> You also get Thread.currentThread().getClass() if you call
> StackWalker.getCallerClass() from main().
>
> Because who is the caller of main()?
I would say there is no Java caller in that case and return
Optional.empty().
No Java caller means there is no bytecode in a class doing the
invocation, so there is no java.lang.Class to identify it. Subsituting
that for Thread.currentThread().getClass() looses information. In the
following example, one can not distinguish between two situations:
public class StackWalkerDemo extends Thread {
@Override
public void run() {
System.out.println("I was called from: " + new
StackWalker(StackWalker.Option.CLASS_REFERENCE).getCallerClass());
}
public static void main(String[] args) throws Exception {
StackWalkerDemo demo = new StackWalkerDemo();
demo.run();
demo.start();
demo.join();
}
}
Prints:
I was called from: class StackWalkerDemo
I was called from: class StackWalkerDemo
The 1st is clearly an invocation from the method in class
StackWalkerDemo (main()), but the 2nd is not.
Regards, Peter
>
> cheers,
>
> -- daniel
>
> On 03/11/15 13:45, Peter Levart wrote:
>> Hi Mandy,
>>
>> Great API.
>>
>> One thing I noticed is method StackWalker.getCallerClass() which is
>> described as equivalent to the following:
>>
>> walk((s) -> s.map(StackFrame::getDeclaringClass)
>> .skip(2)
>> .findFirst()).orElse(Thread.currentThread().getClass());
>>
>> ... the .orElse is presumably meant for the case when getCallerClass()
>> is called directly from within Thread.run() method right? In that case
>> Thread's implementation class is presented as the one doing the
>> invocation of Thread.run(), which seems logical.
>>
>> But what about if getCallerClass() is called from a method that has been
>> invoked from native code via JNI in a newly attached thread that was not
>> started in Java (like the main method)? We will also get the Thread's
>> implementation class as the caller. Is this still logical?
>>
>> 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?
>>
>> So returning java.lang.Class objects is safe now there is jigsaw to
>> enforce isolation when doing reflection on them. It's great to see how
>> things fall together nicely.
>>
>> Regards, Peter
>>
>> On 10/30/2015 08:04 PM, Mandy Chung wrote:
>>> JEP 259:http://openjdk.java.net/jeps/259
>>>
>>> Javadoc for the proposed StackWalker API:
>>>
>>> http://cr.openjdk.java.net/~mchung/jdk9/jep259/api/java/lang/StackWalker.html
>>>
>>>
>>>
>>> A simple way to walk the stack:
>>>
>>> StackWalker walker = new
>>> StackWalker(StackWalker.Option.CLASS_REFERENCE);
>>> walker.walk((s) -> s.filter(f ->
>>> interestingClasses.contains(f.getDeclaringClass())).findFirst());
>>>
>>> The current usage of sun.reflect.Reflection.getCallerClass(int depth)
>>> can be replaced with this StackWalker API.
>>>
>>> Any feedback on the proposed API is appreciated.
>>>
>>> Mandy
>>>
>>> P.S. webrev of the current implementation:
>>> http://cr.openjdk.java.net/~mchung/jdk9/jep259/webrev.00/
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
>
More information about the core-libs-dev
mailing list