Hi all, I post this also to the Avalon list, because while tracking this SitemapSource issue I found a Avalon Logging issue also.
Ok, what happen: Calling a Cocoon Source "cocoon://....." the Pipeline inside the Sitemap is called twice. The reason is the following code inside the SitemapSourceFactory public void release( Source source ) { if ( null != source ) { if ( this.getLogger().isDebugEnabled() ) { this.getLogger().debug("Releasing source " + source.getURI()); } ((SitemapSource)source).recycle(); } } The problem is the source.getURI() inside the logging statement. Why? Because the source is already reset after the serialization and a call to source.getURI initialize the source again and this calles the Sitemap again :-( My proposal is, remove the source.getURI from the logging statement or change the getURI() implementation to not init the Source again. I am not sure if this URI can change after it is init? Now to the Avalon Logging issue. Hm I am wondering why if ( this.getLogger().isDebugEnabled() ) was true, because I had no log-level configured as DEBUG. After a long time of debugging :-( I found two things. 1. org.apache.avalon.framework.logger.LogKit2AvalonLoggerAdapter In the method: public static org.apache.log.Logger createLogger( final Logger logger ) { final Hierarchy hierarchy = new Hierarchy(); final org.apache.log.Logger logKitLogger = hierarchy.getLoggerFor( "" ); final LogKit2AvalonLoggerAdapter target = new LogKit2AvalonLoggerAdapter( logger ); logKitLogger.setLogTargets( new LogTarget[ ] { target } ); return logKitLogger; } a logKitLogger is created with "hierarchy.getLoggerFor( "" )" this defaults the loglevel to DEBUG. The orig Logger is wrapped inside the LogTarget, so the result loglevel of the logger is allways DEBUG independant of the orig Logger setting. I have add the following code after the creation of the logKitLogger if (!logger.isDebugEnabled()) { if (!logger.isWarnEnabled()) { if (!logger.isErrorEnabled()) { logKitLogger.setPriority(Priority.FATAL_ERROR); } else { logKitLogger.setPriority(Priority.ERROR); } } else { logKitLogger.setPriority(Priority.WARN); } } and vola, now the isDebugEnabled inside the SitemapSourceFactory return false :-) But then I wonder why is the Logger inside the SitemapSourceFactory is a wrapped Logger, because SitemapSourceFactory impl. LogEnabled, so the wrapping isn't needed. After an additional debugging session I found the reason. 2. org.apache.avalon.excalibur.component.DefaultComponentFactory Method newInstance first checks if a Component implements "LogEnabled" and after this it checks for "Loggable". The problem is, if a Component impl. AbstractDualLogEnabled like ExcaliburComponentSelector the "setLogger" method of AbstractDualLogEnabled impl. overwrites the prev. set Logger with a wrapped LogKitLogger. Hm, I changed the order and put the check for "LogEnabled" after the "Loggable" and :-) the Logger isn't a wrapped LogKitLogger anymore. Switch back to Cocoon: There are a lot of Components inside the cocoon.xconf which has no logger configured inside the configuration. Example are "Source Factories" and most of the Selectors itself. <input-modules> <output-modules> <source-factories> Should we change this? Sorry for such a long mail, but I hope this helps improve the performance of Cocoon ;-) While debugging all this stuff I thought it's time to switch to a new Container which hasn't all this Adapter/Wrapper classe ;-) Volker