Jess Holle wrote:
Jess Holle wrote:

Okay, I did a bit more digging.

*If*:

   * Your web app contains log4j.jar *and* commons-logging.jar.
   * You do not have log4j installed in any of Tomcat's own lib
     directories.
   * You use a JNDI or other contextual classloader based
     LogRepositorySelector.

*Then*:

   * The first Tomcat web application will "steal" loggers from the
     Tomcat base, i.e. any that happen to be obtained while the first
     web app's contextual classloader is active.
         o In a brief, simple test, whichever web app receives the
           first JSP page request will "steal" the following Tomcat
           loggers:
               + org.apache.jasper.compiler.Compiler
               + org.apache.jasper.compiler.JspReader
               + org.apache.jasper.runtime.PageContextImpl
               + org.apache.jasper.servlet.JspServletWrapper
               + org.apache.jasper.xmlparser.ParserUtils
   * By "steal", I mean that these loggers end up in the
     LoggerRepository of the given web app. Their configuration is thus
     controlled by it.  Also, they use the log4j library from the given
     web app.

There's nothing unexpected here: Jasper is a regular servlet, and thus all of its classes will be loaded with the webapp's classloader. It's basically like if you had the Jasper JARs inside /WEB-INF/lib. The problem then is that Jasper uses static logger instances, while it should either log to the servlet context or have per instance loggers, as it resides in a classloader shared across webapps. Regardless of what happens, we will need to cleanup Jasper's logging behavior.


Another completely different strategy for acquiring loggers is to use the CL which loaded the class (ie, to use straight delegation). There's the problem that it could cause classcast exceptions, however, and it's more annoying to configure.

Both solutions behave differently, but they have their own merits. I happen to prefer the context classloader oriented one in a J2EE environment (so it was used for the java.util.logging implementation I added recently based on some user submitted code that I heavily modfied - see http://issues.apache.org/bugzilla/show_bug.cgi?id=33143).

I could always be mistaken, but my examination of the LoggerRepository's involved seems pretty conclusive.

If one has to have log4j and commons-logging in one's web app, then the only solution appears to be to put log4j in Tomcat and use a non-contextual classloader based LogRepositorySelector. Avoiding the contextual classloader based LogRepositorySelector only keeps Tomcats loggers from sharing the web app's intended LoggerRepository -- they still use the web app's log4j and its default LoggerRepository.

Rémy

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to