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/










Reply via email to