Bug 48220 - LoggingEvent.mdcCopy serialization with non-serializable MDC-values
Summary: LoggingEvent.mdcCopy serialization with non-serializable MDC-values
Status: NEW
Alias: None
Product: Log4j - Now in Jira
Classification: Unclassified
Component: Other (show other bugs)
Version: 1.2
Hardware: PC Windows XP
: P3 minor
Target Milestone: ---
Assignee: log4j-dev
Depends on:
Reported: 2009-11-18 02:10 UTC by Lars Beuster
Modified: 2009-11-19 02:16 UTC (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description Lars Beuster 2009-11-18 02:10:14 UTC
The field mdcCopy in LoggingEvent should be transient. Otherwise it is tried to serialize the Hashtable with all its elements (e.g. in SocketAppender). But these elements doesn't have to be serializable. And if they are not I get an exception and the Logger is unusable for the rest of the Java process.

How to reproduce
- MDC.put("key", notSerializableObject)
- Log on a SocketAppender
Comment 1 Lars Beuster 2009-11-18 02:25:42 UTC
Of cource, if the field is transient then the LoggingEvent at the other side of the SocketAppender is incomplete - probably this is not what I want;)

So if it is intended to leave the field non-transient, at least the documentation for the MDC should be improved to give a hint to problem: non-serializable MCD-value / serializing appende.
Comment 2 Curt Arnold 2009-11-18 19:42:16 UTC
I'm thinking that the most desirable resolution was to substitute Object.toString() for the non-serializable values in the MDC when serializing the logging event.  Will have to pull out my serialization spec to see if there is a clean way to do it.
Comment 3 Lars Beuster 2009-11-19 02:16:07 UTC
Yes, the toString()-call could be a good idea and would solve the problem for non-serializable values.

But I had also another problem. I've put my own serializable object into the MDC-context. But it couldn't be deserialized at the other side because my classfile wasn't present there.
In my special case I've put an application object into the MDC-context. I didn't want to use the toString()-presentation because this method was too heavy. My object was only used in an ErrorAppender with a PatternLayout that used the MDC-value. So toString() was only called in an error case.
Another developer had a SocketAppender in his log4j.xml in conjunction with log4eclipse as the server socket - and ran into the problem.

So for now I've created a SocketAppender-subclass that modifies the LoggingEvent by replacing the mdcCopy-values with it's toString()-representations - per reflection because the fields are private. The heavy toString()-method of my object is now called on every logging event (not only in an error case) - but that's ok, since it's a developer system.

But I don't know if this is a solution that is suitable for everybody using log4j. Perhaps it's possible to activate this behavior with a special option (global or local on every serializing appender).