JDK-8140450 : Implement JEP 259: Stack-Walking API
Type:Sub-task
Component:core-libs
Sub-Component:java.lang
Affected Version:9
Priority:P3
Status:Resolved
Resolution:Fixed
Submitted:2015-10-24
Updated:2020-07-15
Resolved:2015-11-23
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
This issue is for JEP 259: Stack-Walking API integration.
Comments
There is a long discussion on the behavior of StackWalker::getCallerClass when there is no caller frame. This captures the alternatives considered. [1] describes the JDK use cases of getCallerClass and concludes that the user needs the ability to differentiate if there is no caller frame.
The alternatives considered for getCallerClass to return when it���s called by the last frame on the stack (i.e. main() or from a JNI invoked method).
1. Optional.empty
2. null
3. StackWalker.NoCaller.class
4. last frame
5. Thread.class
6. throw an exception - not supported
getCallerClass is intended for frameworks to find the caller on behalf.
For 1-4, the caller-sensitive API will have to handle this corner case explicitly.
Class<?> caller = walker.getCallerClass(); // #1 it will do Optional.orElse or something
if (caller is present) {
// common path
:
} else {
// need to decide what to do
}
#1 and #2 are a better option than #3 and #4 that it will get an exception if the user forgets to handle the no caller frame case.
#5 returning Thread.class - the user can���t differentiate between no caller frame case vs Thread::run case.
This API is intended for framework to use getting the caller and do the operation on behalf. It���s rare that such API is invoked from newly JNI attached thread. JDK caller-sensitive methods might be invoked via JNI attached thread and JDK is not going to use StackWalker::getCallerClass. The public static void main calling getCallerClass.
#1, #2, #6 are the options to be chosen from.
#1 incurs an extra object allocation but the common case always has a caller.
#2 forces null check at every usage
#6 the API expected to be invoked by JNI newly attached thread will have to call StackWalker::walk instead.
IMO, #6 is the best approach such that the common cases are not impacted. If it's determined in the future that a need of a convenient method to find caller that may be absent, a new method could provide a new getCallerClassOrNull method in the future.