logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "David Tonhofer, m-plify S.A." <d.tonho...@m-plify.com>
Subject Serious letdown when trying to log4j in Tomcat. Unsolvable?
Date Mon, 12 Jan 2004 20:42:37 GMT

This has probably cropped up before? Correct me if I'm wrong (I'm
always happy to get an earful about nonexisting problems) but...:

The gist:

  "In some (most?) cases you cannot use a 'log4j.properties'
   file placed in your web application's WEB-INF/classes

...this goes counter to the Log4J's documentation, which says:

  "The default log4j initialization is particularly useful in web-server
  environments. Under Tomcat 3.x and 4.x, you should place the
  log4j.properties under the WEB-INF/classes directory of your
  web-applications. Log4j will find the properties file and initialize
  itself. This is easy to do and it works."

So why doesn't it work?

-> When Tomcat starts up and one of its own classes and/or
   some classes in its "common" or "shared" classloaders use
   log4j (possibly indirectly through commons-logging), then:

-> Tomcat will initialize log4j logging through the relevant
   classloaders (named "StandardClassloader"). Unfortunately,
   whatever is in a Webapp is completely invisible to such a
   classloader. Thus, the file log4.properties in the
   WEB-INF/classes directory is irrelevant at this point.

-> At the first request of a Servlet, the WebappClassloader
   could in principle start log4j initialization using the
   log4j.properties file because it is visible to it.
   Unfortunately, at that moment, the org.apache.log4j.LogManager
   class has already been loaded, its static initializer executed.
   And thus, initialization will not be done again.

This can be easily seen by switching LogLog logging on and
by adding some test code to a servlet.

On Tomcat startup, we get the details of the classloaders. They
are all called 'StandardClassLoader' and the last message is:

  log4j: Trying to find [log4j.properties] using 
  log4j: Could not find resource: [null].
  log4j:WARN No appenders could be found for logger 
  log4j:WARN Please initialize the log4j system properly.
  Starting service Tomcat-Standalone
  Apache Tomcat/4.1.24

As you can see, "org.apache.commons.digester.Digester" caused
premature initialization.

The servlet, containing this code (essentially the same as the one called
by LogManager):

  Method method = Thread.class.getMethod("getContextClassLoader", null);
  ClassLoader ccl = (ClassLoader) method.invoke(Thread.currentThread(), 
  URL url = ccl.getResource("log4j.properties");
  LogLog.debug(url.toString() + " using " + ccl + ".");

will give this output:

  log4j: setFile called: velocity.log, true
  log4j: setFile ended
file:/C:/eclipse/workspace/log4jtest/WEB-INF/classes/log4j.properties using 
    delegate: false
  ----------> Parent Classloader:
    delegate: true

I don't see that this problem is in any way solvable. Also, should it be?
Wouldn't log-configuration from the webapp give the webapp too much power
over Tomcat? It probably would.

The solution is of course to move the 'log4j.properties' file higher: ask
the friendly BOFH to move it into the 'common-classes' for example. But
that's another story.

Best regards,

	-- David Tonhofer

To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org

View raw message