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



Reply via email to