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