Bug 49920 - DailyRollingFileAppender.rollOver() might leave superclass's WriterAppender.qw as null causing NullPointerExceptions when logging events
Summary: DailyRollingFileAppender.rollOver() might leave superclass's WriterAppender.q...
Status: NEW
Alias: None
Product: Log4j - Now in Jira
Classification: Unclassified
Component: Appender (show other bugs)
Version: 1.2
Hardware: PC Linux
: P2 major
Target Milestone: 1.2.18
Assignee: log4j-dev
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-13 08:33 UTC by Piotr Bzdyl
Modified: 2013-04-25 05:07 UTC (History)
0 users



Attachments
Proposed simple patch for fix this (2.00 KB, patch)
2010-10-13 14:07 UTC, yerenkow
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Piotr Bzdyl 2010-09-13 08:33:04 UTC
DailyRollingFileAppender.rollOver() method catch a FileNotFoundException from FileAppender superclass setFile method:

this.setFile(fileName, true, this.bufferedIO, this.bufferSize);

When this exception is thrown, WriterAppender.qw might be left as null causing all further subAppend(LoggingEvent) invocations failed with NullPointerException.

I noticed that setFile might fail with FileNotFoundException when the filesystem is full and even an empty file cannot be created. The scenario is as follows (code from http://repo1.maven.org/maven2/log4j/log4j/1.2.16/log4j-1.2.16-sources.jar):

1. current log file name is "test.log"
2. a filesystem where test.log is kept become full
3. DailyRollingFileAppender.rollOver() method successfully closes current (test.log) file and successfully renames it to a timestamped file (test.log.yyyy-MM-dd)
4. DailyRollingFileAppender.rollOver() calls setFile from FileAppender superclass to open the current log file (test.log) again. When setFile is called that file doesn't exist as it was previously renamed to a timestamped filename. Following code from FileAppender.setFile(...) will throw FileNotFoundException:

FileOutputStream ostream = null;
    try {
          //
          //   attempt to create file
          //
          ostream = new FileOutputStream(fileName, append);
    } catch(FileNotFoundException ex) {
          //
          //   if parent directory does not exist then
          //      attempt to create it and try to create file
          //      see bug 9150
          //
          String parentName = new File(fileName).getParent();
          if (parentName != null) {
             File parentDir = new File(parentName);
             if(!parentDir.exists() && parentDir.mkdirs()) {
                ostream = new FileOutputStream(fileName, append);
             } else {
                throw ex;
             }
          } else {
             throw ex;
          }
    }
FileNotFoundException can be thrown if it is impossible to create a new empty file when the filesystem is full.

5. DailyRollingFileAppender.rollOver() will catch that exception and log it using error handler and then continue its flow. It will leave its QuietWriter qw field set to null.

Each next logging event passed to subAppend method will cause NullPointerException (and in case of AsyncAppender calling it will cause AsyncAppender async thread to die as it doesn't catch NPE).
Comment 1 yerenkow 2010-10-13 14:07:41 UTC
Created attachment 26172 [details]
Proposed simple patch for fix this

If new file creation failed, at each next event appender will try to create file.

Patch tested with several run-out-of-space events, occured in one lifetime of app.
Working ;)
Comment 2 yerenkow 2013-04-25 05:07:13 UTC
Is this going to be fixed?