Proposed API for JEP 259: Stack-Walking API

Peter Levart peter.levart at gmail.com
Tue Nov 17 19:54:28 UTC 2015



On 11/16/2015 08:16 PM, Mandy Chung wrote:
>> On Nov 15, 2015, at 10:59 AM, Peter Levart <peter.levart at gmail.com> wrote:
>>
>> OTOH in the described cases, a caller of walker.getCallerClass() is actually expecting to be called by a Java method, right? So what would it be if such "caller-sensitive" method demanded to be called by a Java method and throw IllegalArgumentException("Not called by Java method") otherwise?
>>
>> Have you thought of that possibility?
> Are you thinking about a JNI method calling getCallerClass?  Or refer getCallerClass being the bottom of the stack?
>
> I don’t see any issue for a JNI method calling getCallerClass and it’s doing:
> *     Class<?> caller = walker.walk(s ->
> *         s.map(StackFrame::getDeclaringClass)
> *          .skip(2)
> *          .findFirst());
>
> Mandy

Hi Mandy,

No, I was not thinking of StackWalker::getCallerClass being called by 
JNI. I was thinking of a "caller-sensitive" method calling 
getCallerClass() and that "caller-sensitive" method being called by JNI 
from a newly attached thread.

1st, I don't think anyone will attempt calling getCallerClass() from the 
static main() method invoked by java launcher. That's silly and need not 
be supported.
2nd, I don't think anyone will attempt calling getCallerClass() from 
overridden Thread::run() method. That too need not be supported.

So what we are left with are other "caller-sensitive" methods calling 
getCallerClass(). Like for example:

public class Strings {
     public static ResourceBundle getBundle() {
         Class<?> cc = stackWalker.getCallerClass();
         return ResourceBundle.getBundle(cc.getName() + "$Strings", 
Locale.getDefault(), cc.getClassLoader());
     }
}

Such method obviously expects to be called by some Java method. So it 
may as well demand it. By throwing exception if it is called by JNI from 
newly attached thread.

"caller-sensitive" methods could be viewed as taking an implicit 
parameter - their caller. If that parameter is not specified, they could 
behave like when some other explicit parameter was not specified or 
invalid - throw new IllegalArgumentException("Not called by Java 
method") ...

So instead of "pretending" they were called by themselves, which might 
not be right, simply refuse the invocation with exception. I don't think 
this would hinder any such caller-sensitive method in it's utility. More 
importantly, it would prevent such methods from being abused.

You said about possible use-cases for getCallerClass:

> I have been thinking what the users would do when there is no caller.
>
> The JDK use  of getCallerClass are to:
> 1. find the caller's class loader for class loader hierarchy check

Abuse: calling such "caller-sensitive" method by JNI from newly-attached 
thread would use the caller-sensitive method's declaring class 
ClassLoader for hierarchy check - wrong!

> 2. find the caller’s class loader to load something on behalf of the 
> caller (visibility)

Abuse: ... would use the caller-sensitive method's declaring class 
ClassLoader to load something - might work, might not

> 3. looking forward to work with modules, one would want to get the 
> caller’s module
> - to load something on behalf of the caller's module

Abuse: ...would load something from caller-sensitive method's declaring 
class module - wrong.

> - to add read edge to the caller’s module before accessing its type

Abuse: ...would add a read edge to itself before accessing some type - 
wrong.


In all those cases throwing exception would be the right thing to do.


What do you think?

Regards, Peter




More information about the core-libs-dev mailing list