[slf4j-dev] [Bug 238] New: MDC.mdcAdapter is not thread safe.

bugzilla-daemon at pixie.qos.ch bugzilla-daemon at pixie.qos.ch
Thu Sep 1 21:06:52 CEST 2011


http://bugzilla.slf4j.org/show_bug.cgi?id=238

           Summary: MDC.mdcAdapter is not thread safe.
           Product: SLF4J
           Version: 1.6.x
          Platform: Macintosh
        OS/Version: Mac OS X 10.3
            Status: NEW
          Severity: blocker
          Priority: P1
         Component: Core API
        AssignedTo: slf4j-dev at qos.ch
        ReportedBy: zhaotq at gmail.com


In my tomcat environment, logback throws NullPointerException occasionally. The
satack trace looks like:

Exception in thread "Thread-5" java.lang.NullPointerException
        at
ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:135)
        at
ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:471)
        at ch.qos.logback.classic.Logger.filterAndLog_2(Logger.java:464)
        at ch.qos.logback.classic.Logger.debug(Logger.java:542)
        at
com.alu.ipd.ode.customer.exponentiale.reporting.ram.RamMonitor$RamServerChecker.run(RamMonitor.java:140)


Look at the code of LoggingEvent.java around line 135:
    LogbackMDCAdapter logbackMDCAdapter = (LogbackMDCAdapter) MDC
        .getMDCAdapter();
    mdcPropertyMap = logbackMDCAdapter.getPropertyMap();

Sometime the MDC.getMDCAdapter() returns null, which caused the
NullPointerException.

I did a lot of debugging, found that the exception would not happen if I
watched the MDC.mdcAdapter with the debugger also found no changed to it.

I believed that this must be a threading issue, and modified the MDC's static
initializer as below:

  static final MDCAdapter mdcAdapter;


  static {
    MDCAdapter mdcAdapter1=null;
    try {
      mdcAdapter1 = StaticMDCBinder.SINGLETON.getMDCA();
    } catch (NoClassDefFoundError ncde) {
      mdcAdapter1 = new NOPMDCAdapter();
      String msg = ncde.getMessage();
      if (msg != null && msg.indexOf("org/slf4j/impl/StaticMDCBinder") != -1) {
        Util.report("Failed to load class
\"org.slf4j.impl.StaticMDCBinder\".");
        Util.report("Defaulting to no-operation MDCAdapter implementation.");
        Util
            .report("See " + NO_STATIC_MDC_BINDER_URL + " for further
details.");
      } else {
        throw ncde;
      }
    } catch (Exception e) {
      // we should never get here
      Util.report("MDC binding unsuccessful.", e);
    } finally {
        mdcAdapter = mdcAdapter1;
    }
  }

NOTE: The key here is: make the mdcAdapter final. I used a temporary variable
mdcAdapter1 and assigned it to mdcAdapter in the finally clause.

After this change, the NullPointerException never happens.

I used slf4j 1.6.2 and logback 0.9.29.

-- 
Configure bugmail: http://bugzilla.slf4j.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.


More information about the slf4j-dev mailing list