Thoughts on adding getElementClass() method to StackTraceElement?

Peter Levart peter.levart at gmail.com
Mon Jun 17 06:55:04 UTC 2013


On 06/15/2013 09:59 PM, Nick Williams wrote:
> On Jun 15, 2013, at 2:22 PM, Remi Forax wrote:
>
>> Could you be a little more clear why you need a class for your logging API, exactly, why the class name is not enough for logging purpose ?
> Certainly. Log4j 2 offers "extended stack trace" patterns. When exceptions or stack traces are logged, or when displaying the location that the logging statement originated from, the stack trace/log also reveals the resource (JAR file, directory, etc.) that the class was loaded from and the implementation version from the package the class is in. This helps reveal possible class loading issues (among other things), which can be an extremely valuable tool when troubleshooting problems with an application.
>
> Log4j 2 accomplishes this by getting the class associated with a StackTraceElement (as outlined below), and then 1) getting the Package from the Class and the version from the Package, and 2) getting the ProtectionDomain from the Class, getting the CodeSource from the ProtectionDomain, and getting the JAR/URL from the CodeSource. The last two parts are easy. It's getting the Class from the StackTrace that is extremely inefficient if not done right. Java 8 took away the best way we had found to do that (which, admittedly, was because we were relying on a non-standard class, which isn't recommended).
>

On 06/17/2013 08:12 AM, Peter Levart wrote:
> New API could be entirely unrelated to Throwable, if there was support 
> for it in native code. Since there would have to be changes to the 
> native code anyway to support this, why not create a separate API? 

If I understand this correctly, one part of your code is displaying the 
"resource location" of each method's declaring class in the stack trace 
when such "extended stack trace" is configured. Therefore you need this 
API to capture the class-enriched-stack-trace at the time the Throwable 
instance is constructed. No special Throwable-unrelated API to return 
the stack trace would be suitable for this purpose then.

But for the purpose of displaying the "resource location" of the class 
invoking the logging API, you don't need the entire stack trace, just 
the immediate caller class, right? When @CallerSensitive internal 
annotation was introduced (and Reflection.getCallerClass(int frames) was 
dropped), there was some debate about possible introduction of public 
API that could be used to reveal the caller's class. Perhaps there's 
still time to create such API for JDK8? At least one part of your 
logging functionality would be covered with such API.

Suppose the API to obtain the immediate caller class (j.l.Class object) 
was public and fast, so you could do that for each call to the logging 
API eagerly (after initial check for logging level). Now, could you 
delay the evaluation of "extended stack trace" pattern to the latest 
time possible, when you must format the stack-trace? Would calling 
Class.forName(name, false, classLoader) for each individual 
StackTraceElement, using the ClassLoader of the caller class, still 
present a performance problem? You would only get locations for classes 
that the caller has access to, so no inaccessible information could be 
revealed.

Regards, Peter




More information about the core-libs-dev mailing list