Now that I am looking at this, deep cloning is hard to do generically. Looping through a collection, you can't just try to call clone() on each element because clone() is protected in Object and Cloneable is only a marker interface. So, you have to (1) know the type of the object and cast it before cloning, (2) use reflection to call clone or (3) clone via serialization.
(3) is too slow. (2) is probably the best generic solution for a library like log4j, but would benefit from caching of the reflection information as it is looked up (this may be non-trivial if classes reload...but I understand BeanUtils (from jakarta commons) may do this) (1) is probably the best all around, but would best be done using a pluggable container like I described earlier, so log4j doesn't have to deal with it...in this case, the implementer can either know which things to clone or make sure cloneable items implement an additional mypackage.Cloneable interface with a public clone method in it. Sure is a bummer when these things spin out of control like this. I am going to implement this locally using your latest suggestion and simple, non-cached reflection for now. I need code in place within the hour, so this will stop gap. Please comment. -C -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Sent: Wednesday, January 28, 2004 8:04 AM To: Log4J Developers List Subject: Re: MDC copies Christian, We could simply add a deep MDC copy method to LoggingEvent and add an option to AsyncAppender so that deep MDC copy method would be called. The problem with deep copying, or even with the shallow copying we do currently, is the incurred performance hit. The whole point of AsyncAppender was to improve performance. Given that that deep copying is necessary only when using AsyncAppender, using it starts to become counterproductive at some point. Pardon my ignorance but is there a way to tell a java.util.Collection to deep copy? At 04:48 PM 1/27/2004 -0500, [EMAIL PROTECTED] wrote: >I am new to this list but have been using log4j for years. I have a >possible need to modify the framework: > >I am putting mutable objects in MDC and this breaks down when using the >AsyncAppender (see bug #5932). As a solution, I would like to do a deeper >copy of MDC. > >I have wrapped calls to Logger via my own Logger, so I can create >custom >LoggingEvents if need be that can offer their own getMDCCopy, getMDC and >custom serialization (which I am not quite sure is reasonable as I am not >familiar with custom serialization in a subclass), but I thought another >possibility would be to add a pluggable MDC container to the MDC class so >that instead of using the log4j ThreadLocalMap, I could use my own >thread-local map that has a smarter clone method. > >This latter solution would require a modification to log4j code, which >I >would like to avoid unless I can contribute it and get it out of my >maintenance loop once the next release comes out. If this is deemed a >legitimate approach, I would think that making the tlm variable implement >a Map (or some subset of Map) would be best. Then the default >ThreadLocalMap could still use a Hashtable (why?) and expose it via the >Map interface. MDC's strategy for creating it's container would be to >instantiate the class configured either via the configurator, system >properties or maybe just MDC.setContainerClass(Class clazz) (I could use >some input as to how best to expose this customization). > >Also, LoggingEvent's getMDCCopy method would need to expect only a Map, >not a Hashtable. > >Any ideas or votes would be helpful as I need a solution to this >problem >quickly. Also, are CVS patches required to contribute or can I just send >an alternate file (I'll read the FAQ in case the answer is in there)? > >Regards, > >Christian Hall -- Ceki G�lc� For log4j documentation consider "The complete log4j manual" ISBN: 2970036908 http://www.qos.ch/shop/products/clm_t.jsp --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
