Alex created Bug LOGBACK-1087
Issue Type: Bug Bug
Affects Versions: 1.1.3, 1.1.2
Assignee: Logback dev list
Components: logback-classic
Created: 09/Jul/15 11:54 AM
Description:

ConcurrentModificationException can be thrown whilst status event is fired out into registered StatusListeners but one of the listener is removed at the same time from a different thread.

An example of stack trace for the issue is provided below

11:31:11,081 |-ERROR in ch.qos.logback.core.rolling.RollingFileAppender[logfile] - Appender [logfile] failed to append. java.util.ConcurrentModificationException
    at java.util.ConcurrentModificationException
    at     at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at     at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at     at ch.qos.logback.core.BasicStatusManager.fireStatusAddEvent(BasicStatusManager.java:86)
    at     at ch.qos.logback.core.BasicStatusManager.add(BasicStatusManager.java:59)
    at     at ch.qos.logback.core.recovery.ResilientOutputStreamBase.addStatus(ResilientOutputStreamBase.java:157)
    at     at ch.qos.logback.core.recovery.ResilientOutputStreamBase.addStatusIfCountNotOverLimit(ResilientOutputStreamBase.java:138)
    at     at ch.qos.logback.core.recovery.ResilientOutputStreamBase.postIOFailure(ResilientOutputStreamBase.java:101)
    at     at ch.qos.logback.core.recovery.ResilientOutputStreamBase.flush(ResilientOutputStreamBase.java:82)
    at     at ch.qos.logback.core.encoder.LayoutWrappingEncoder.doEncode(LayoutWrappingEncoder.java:137)
    at     at ch.qos.logback.core.OutputStreamAppender.writeOut(OutputStreamAppender.java:194)
    at     at ch.qos.logback.core.FileAppender.writeOut(FileAppender.java:209)
    at     at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:219)
    at     at ch.qos.logback.core.rolling.RollingFileAppender.subAppend(RollingFileAppender.java:182)
    at     at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:103)
    at     at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88)
    at     at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:48)
    at     at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:273)
    at     at ch.qos.logback.classic.Logger.callAppenders(Logger.java:260)
    at     at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:442)
    at     at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:396)
    at     at ch.qos.logback.classic.Logger.error(Logger.java:559)

The easiest way to reproduce it would be to implement status listener unregistering itself from addStatusEvent:

class MyListener implements StatusListener
{
  private StatusManager _statusManager;
  public MyListener(StatusManager statusManager)
  {
    _statusManager = statusManager;
  }

  @Override
  public void addStatusEvent(Status status)
  {
    _statusManager.remove(this);
  }
}

The issue affects the application creating and removing Appenders dynamically and registering/unregistering StatusListeners on appender creation and removing accordingly.

Project: logback
Priority: Major Major
Reporter: Alex
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira