Proposed API for JEP 259: Stack-Walking API

Timo Kinnunen timo.kinnunen at gmail.com
Tue Nov 17 22:50:38 UTC 2015


Hi, 

I’m happy to hear that, I was just about to post more convoluted examples against special-casing (i.e.

		new Thread(r).start();
vs.
		new Thread(r) {}.start();
vs.
		new Thread(new Thread(r)) {}.start();
vs.
		new Thread(new Thread(r) {}).start();
). 

Apart from the orphaned paragraph fragment at the end looks good to me, but that’s just my opinion.



Sent from Mail for Windows 10



From: Mandy Chung
Sent: Tuesday, November 17, 2015 23:43
To: Peter Levart
Cc: OpenJDK Dev list
Subject: Re: Proposed API for JEP 259: Stack-Walking API



> On Nov 17, 2015, at 2:09 PM, Peter Levart <peter.levart at gmail.com> wrote:
> 
> I think that calling getCallerClass() from implementation of Runnable::run should expect it to return a system class. It may be Thread.class or ThreadPoolExecutor$Worker.class or anything actually. 
> 

I’m now convinced that it’s not a good idea to special case it.  getCallerClass will simply return the caller frame (i.e. top-2) on the stack and throw UOE if there is no caller frame.  The user should call StackWalker::walk instead if this special case matters.

How does this look?

/**
 * Gets the {@code Class} object of the caller invoking the method
 * that calls this {@code getCallerClass} method.
 *
 * <p> Reflection frames, {@link java.lang.invoke.MethodHandle} and
 * hidden frames are filtered regardless of the
 * {@link Option#SHOW_REFLECT_FRAMES SHOW_REFLECT_FRAMES}
 * and {@link Option#SHOW_HIDDEN_FRAMES SHOW_HIDDEN_FRAMES} options
 * if this {@code StackWalker} has been configured.
 *
 * <p> This method throws {@code UnsupportedOperationException} if
 * this {@code StackWalker} is not configured with
 * {@link Option#RETAIN_CLASS_REFERENCE RETAIN_CLASS_REFERENCE} option
 * or this method is called from the last frame on the stack,
 * i.e. invoked from a JNI attached thread (
 * for example, {@code static public void main} method launched by the
 * {@code java} launcher).
 *
 * @apiNote
 * For example, {@code Util::getResourceBundle} loads a resource bundle
 * on behalf of the caller.  It calls this {@code getCallerClass} method
 * to find the method calling {@code Util::getResourceBundle} and use the caller's
 * class loader to load the resource bundle. The caller class in this example
 * is the {@code MyTool} class.
 *
 * <pre>{@code
 *     class Util {
 *         private final StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
 *         public ResourceBundle getResourceBundle(String bundleName) {
 *             Class<?> caller = walker.getCallerClass();
 *             return ResourceBundle.getBundle(bundleName, caller.getClassLoader());
 *         }
 *     }
 *
 *     class MyTool {
 *         private void init() {
 *             ResourceBundle rb = Util.getResourceBundle("mybundle");
 *         }
 *     }
 * }</pre>
 *
 * An equivalent way to find the caller class using the
 * {@link StackWalker#walk walk} method is as follows
 * (filtering the reflection frames, {@code MethodHandle} and hidden frames
 * not shown below):
 * <pre>{@code
 *     Optional<Class<?>> caller = walker.walk(s ->
 *         s.map(StackFrame::getDeclaringClass)
 *          .skip(2)
 *          .findFirst());
 * }</pre>
 *
 * When the {@code getCallerClass} method is called from a method that
 * is the last frame on the stack, i.e. invoked from a JNI attached thread,
 * for example, {@code static public void main} method launched by the
 * {@code java} launcher,
 *
 * @return {@code Class} object of the caller's caller invoking this method.
 *
 * @throws UnsupportedOperationException if this {@code StackWalker}
 *         is not configured with {@link Option#RETAIN_CLASS_REFERENCE
 *         Option.RETAIN_CLASS_REFERENCE}.
 * @throws UnsupportedOperationException if there is no caller frame, i.e.
 *         when this {@code getCallerClass} method is called from a method
 *         which is the last frame on the stack.
 */

Mandy





More information about the core-libs-dev mailing list