On 20/04/2007, at 1:57 PM, Paul Smith wrote:
I'm getting a weird NPE here:
Daemon Thread [Chainsaw-WorkerThread] (Suspended (breakpoint at
line 539 in PatternParser$ClassNamePatternConverter))
PatternParser$ClassNamePatternConverter.getFullyQualifiedName
(LoggingEvent) line: 539
PatternParser$ClassNamePatternConverter(PatternParser
$NamedPatternConverter).convert(LoggingEvent) line: 512
PatternParser$ClassNamePatternConverter(PatternConverter).format
(StringBuffer, LoggingEvent) line: 65
PatternLayout.format(LoggingEvent) line: 504
EventDetailLayout.format(LoggingEvent) line: 280
LogPanel$DetailPaneUpdater.updateDetailPane() line: 2552
LogPanel$DetailPaneUpdater.setSelectedRow(int) line: 2531
LogPanel$DetailPaneUpdater.access$1(LogPanel$DetailPaneUpdater,
int) line: 2529
LogPanel.receiveEventBatch(String, List) line: 1398
ChainsawAppenderHandler$WorkQueue$WorkerThread.dispatchEventBatch
(ChainsawEventBatch) line: 343
ChainsawAppenderHandler$WorkQueue$WorkerThread.run() line: 299
This is because the fqnOfCategoryClass variable is null, as is the
LocationInfo. This obviously never happened with 1.3. I wonder if
the 'fake' appender that dispatches events to the GUI is required
to handle something slightly different.
I've been staring at the current 1.2 code and now I finally see the
light.
In EventDetailLayout, we make a copy of the event setting the
fqnCategoryClassName value to null (first constructor arg):
LoggingEvent copy = new LoggingEvent(null,
logger, event.getTimeStamp(),
event.getLevel(),
msg,
threadName,
event.getThrowableInformation(),
ndc,
li,
properties);
Later on, when the PatternParser wants the LocationInfo, because
that's null, it generates a new one, but inside LocationInfo
constructor:
public LocationInfo(Throwable t, String fqnOfCallingClass) {
if(t == null)
return;
......
ibegin = s.lastIndexOf(fqnOfCallingClass);
Since fqnOfCallingClass is null, blam-o inside String.lastIndexOf
(String).
So, why does it fail now in 1.2?
In LoggingEvent in 1.3:
if (locationInfo == null && fqnOfCategoryClass != null) {
locationInfo = new LocationInfo(new Throwable(),
fqnOfCategoryClass);
}
In LoggingEvent in 1.2:
/**
Set the location information for this logging event. The collected
information is cached for future use.
*/
public LocationInfo getLocationInformation() {
if(locationInfo == null) {
locationInfo = new LocationInfo(new Throwable(),
fqnOfCategoryClass);
}
return locationInfo;
}
So, just a subtle change required in the if block in 1.2 code. This
change was done by Ceki in 1.3 trunk via revision 310506:
http://svn.apache.org/viewvc?view=rev&revision=310506
I think we should port this change as well. Any objections?
Paul