[PATCH] 4851444: Exposing sun.reflect.Reflection#getCallerClass as a public API in Java 8

Mandy Chung mandy.chung at oracle.com
Fri Sep 20 07:09:19 UTC 2013

On 9/18/2013 9:22 AM, Nick Williams wrote:
> Okay. Again, sorry for my absence. This wraps up my feedback for now. I now await responses from Mandy.
> On Sep 17, 2013, at 3:53 PM, Mandy Chung wrote:
>> You asked at a good time.  I discussed this with John Rose last couple days on this topic.  He has been thinking about how to do fillInStackTrace performantly and walk the stack with laziness and frame filtering.  The current implementation fills the entire stack trace while Groovy and Log4j use case filters the frames of some specific classes until it reaches the first one not being filtered.
>> He suggests to consider an API taking a callback shape (e.g. Function, Consumer, etc) that Remi Forax suggested at one time that allows the JVM to do something.   I will work with John to work out the details and determine the interface between VM and library and hash out issues.
>> I like the callback shape idea and hope to work out a proposal soon.

This will give you an idea the API we are thinking about:

More work to do as we are working on the VM interface and 
implementation.  We'll post an update when it's ready.

Stack is a "stream" that allows you to walk partial stack (e.g. find 
caller) or full stack trace (e.g. throwable). The filtering and mapping 
operations are lazy to avoid having the VM eagerly copying the entire 
stack trace data even for the short reach case (like Groovy and Log4j).

The API takes a predicate, consumer or function so that the caller will 
only need to carry the data it needs.  There is no method to return the 
stream of stack frames; otherwise, the returned stack frame stream would 
be a snapshot and require to do fillInStackTrace and get the entire 
stack trace. The API can also take a depth limit to control the number 
of elements and can use it as optimization (currently the VM has a 
predefined max number of stack frames returned in a stack trace).

I have modified java.util.logging.LogRecord to infer the caller using 
the new API (much simpler):

     StackTraceElement frame =
         Thread.firstCaller(e -> {return !isLoggerImplFrame(e.getClassName()); },

Replacement for getCallerClass()
     Class<?> c = Thread.getCaller(StackFrameInfo::getDeclaringClass);

Replacement for traversing the stack with getCallerClass(int depth)
     Thread.walkStack(e -> doSomething(e));

We'll be busy at JavaOne next week and if you don't hear from me, that 
explains why.


More information about the core-libs-dev mailing list