Bug 45039

Summary: Use Throwable.getStackTrace to obtain stack trace when JDK 1.4 or later is available
Product: Log4j - Now in Jira Reporter: Curt Arnold <carnold>
Component: OtherAssignee: log4j-dev <log4j-dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 1.2   
Target Milestone: ---   
Hardware: PC   
OS: Mac OS X 10.4   

Description Curt Arnold 2008-05-19 10:31:28 UTC
The LocationInfo constructor obtains the location of the logging request by capturing the output of Throwable.printStackTrace and then parsing it to find the earliest caller of any method on the fully qualified class name.  Unfortunately, this can be sensitive to differences in implementations of Throwable.printStackTrace (see bug 42281 and 30588 for examples) or general weaknesses in the parsing of the output (see bug 44888).

JDK 1.4 added Throwable.getStackTrace() to provide direct access to this info, but since log4j still supports running on earlier platforms it can not depend on the availability of this method.  Building log4j does require at least a JDK 1.4 due to the use of Maven, so it could have explicit calls to Throwable.getStackTrace() as long as it was prepared to catch an exception if the method was not found and would fallback to the JDK 1.3 compatible behavior.  Or it could just use reflection.
Comment 1 Thorbjørn Ravn Andersen 2008-07-02 17:25:46 UTC
(In reply to comment #0)

> JDK 1.4 added Throwable.getStackTrace() to provide direct access to this info,
> but since log4j still supports running on earlier platforms it can not depend
> on the availability of this method.  Building log4j does require at least a JDK
> 1.4 due to the use of Maven, so it could have explicit calls to
> Throwable.getStackTrace() as long as it was prepared to catch an exception if
> the method was not found and would fallback to the JDK 1.3 compatible behavior.
>  Or it could just use reflection.

In my experience having code conforming to a given Java version gives problems especially when having several of these each for their own Java version all put in the same source tree.

Personally I think that the best way to do this kind of "call this method which we know at runtime if it exists or not" is through reflection.  If the code is written and debugged first as a normal Java method it is not hard to transform the finished result into reflection method calls. 
Comment 2 Curt Arnold 2008-08-12 13:28:23 UTC
Committed rev 685300.