The appender tag of xml configuration allows formally to be like that: <appender name="STANDARD_APPENDERS" class=""> <appender-ref ref="CONSOLE.ERR"/> <appender-ref ref="CONSOLE.OUT"/> <appender-ref ref="FILE"/> </appender> According to DTD: <!ELEMENT appender (errorHandler?, param*, layout?, filter*, appender-ref*)> <!ATTLIST appender name ID #REQUIRED class CDATA #REQUIRED > The current implementation of log4j (1.2.15) cannot resolve such a construct (empty class attribute -> ClassNotFountException) My propsal: 1. Allow an empty class attribute if the children are only appender-ref elements. 2. Resolve a reference to such an appender declaration like there would be all three appender-ref's (in logger or other appender declarations).
I wrote this reply after a similar posting on log4j-user after a related post. However, I can't find my reply in the archive, so maybe it did not get there: On Sep 29, 2009, at 8:56 PM, Curt Arnold wrote: I believe it is only used by AsyncAppender and similar appenders that encapsulate another appender. <appender class="org.apache.log4j.AsyncAppender"> <appender-ref ref="console"/> </appender> If you want to reuse configuration fragments, you can use the external entity facility of XML to include any arbitrary XML content from another file. It doesn't work with earlier log4j's, but should work with anything from the last few years. <!DOCTYPE log4j:configuration [ <!ENTITY boilerplate SYSTEM 'boilerplate.xml'> ]> <log4j:configuration....> &boilerplate; </log4j:configuration> The following are new comments: There are multiple places where the DOMConfiguration expects to resolve a appender name and get a single Appender back. Rewriting DOMConfigurator to handle an array of appenders or some similar structure would be a significant modification and may pose compatibility issues. If it were to be done, the easiest way to implement would be to create a CompositeAppender that would delegate to the nested appenders. However, except for the magic of interpreting a blank class name as CompositeAdapter, you could accomplish the same objective by just writing the CompositeAdapter and specifying its class name.
Thanks for the clarifications and suggenstions. If I have time I will look how difficult it would be to implement such a CompositeAppender. BTW: The question one week ago on the users list was also from me. But I did never see any response to it.
Created attachment 24365 [details] contribution CompositeAppender, incl. testcase new implementation of and testcase for CompositeAppender
I have implemented a new CompositeAppender (in fact copied the AsynchAppender and deleted unnecessary code). DOMConfigurator enhanced: empty class attribute is now expanded to new CompositeAppender. Check, if the childs of a CompositeAppender are all appender-ref. Otherwise continue on the loop like it does on other unresolved children. DOMTestCase enhanced by a new test testComposite(), along with new test resource files input/xml/DOMTestCaseCompositeAppender.xml (based on input/xml/DOMTestCase1.xml), witness/dom.A1.composite (based on witness/dom.A1.1) and witness/dom.A2.1 (based on witness/dom.A2.composite). The testcase nearly succeeded: Only the written stacktraces had two more lines, compared to the witness file. Also the existing tests showed this behaviour. I suppose this is due an inconsistence in my developement environment (I ran the tests within eclipse, JDK 1.4) and not because something is wrong implemented. CodeBase: Trunk, Revision 823021 All my changes are marked with " // CHa Heri Bender (CompositeAppender)" Hope you will enjoy my contribution and add it to the repository. Heri