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/