Re: [PATCH] 4851444: Exposing sun.reflect.Reflection#getCallerClass as a public API in Java 8
Jörn Huxhorn
jhuxhorn at googlemail.com
Fri Sep 20 08:50:57 UTC 2013
On 20. September 2013 at 09:28:52, Nick Williams (nicholas+openjdk at nicholaswilliams.net) wrote:
> This will give you an idea the API we are thinking about:
> http://cr.openjdk.java.net/~mchung/jdk8/webrevs/walkstack-webrev/
Just to be clear, this means the patch I worked on for a month has been completely junked. Correct? Awesome.
I'm less than impressed how all this is turning out.
"I expect that at this stage, patches speak louder than words :)"
http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-July/019376.html
I was very happy that Nick actually did just that and proposed a solution. His proposals have been discussed on this list, he listened to the feedback and provided an implementation based on all of that. Thanks for the effort.
> 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).
This is all well and good, but some of us just need a simple array. This seems like over-engineering. I just want an array of StackFrameInfos/StackTraceFrames.
+1
> 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()); },
> StackFrameInfo::stackTraceElement);
>
> Replacement for getCallerClass()
> Class<?> c = Thread.getCaller(StackFrameInfo::getDeclaringClass);
>
> Replacement for traversing the stack with getCallerClass(int depth)
> Thread.walkStack(e -> doSomething(e));
This looks beautiful for Java 8, sure. Now try doing these same things in a library compiled for Java 6 but made to be compatible with Java 8 and so all of this has to happen via reflection. Suddenly it's nightmarish.
+1 again.
This API is great. Lambdas, yay! Nice code. Very awesome & clean.
But I have serious doubts that *this* is going to be more efficient than just iterating over an array.
Feel free to add all that functionality but all we are asking for right now is access to the call stack array in a way that is as fast, or, ideally, even faster than using the current getCallerClass(int) method. Performance is the main reason for this whole discussion.
And it is very, very crucial that all of this can be done via (Java 6) reflection so that code will be able to use sun.reflect.Reflection up to J7 and the new API after that...
Joern.
More information about the core-libs-dev
mailing list