[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