commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simon Kitching <>
Subject Re: [logging] JCL1 LogFactory incompatibility with WAS
Date Wed, 01 Mar 2006 01:24:55 GMT
On Thu, 2006-02-23 at 23:05 +0000, robert burrell donkin wrote:
> JCL 1.1 is incompatible with WAS. this appears to be an existing
> standing issue i
> haven't managed to with work out why this is case (as yet). 
> it does expose another place where JCL throws a runtime exception where
> it might well be better to just use diagnostic logging. there appear to
> be a number of containers who use their own LogFactory implementations
> so that they can hook JCL into their logging system.
> given there are issues, i'll close down JCL1 branch for now and continue
> JCL 1.1 work on trunk.

This same issue has been discussed in a different thread on this same
list today. However I'll reply here for the sake of people searching the
archives for this, and add some more details.

The problem is that WAS deploys commons-logging.jar in a "shared"
classpath location, and also forces commons-logging to load a custom
LogFactory implementation from the shared classpath by setting system
property org.apache.commons.logging.LogFactory to point to custom class

If a webapp also deploys commons-logging in the webapp then:
 * user classes bind to the LogFactory loaded via the webapp
   classloader, due to standard Java rules.
 * The webap copy of LogFactory has been ordered to load the
   specified TrLogFactory;it's only available class via the
   shared classloader and by the standard Java rules this
   binds to the LogFactory loaded via the shared classloader.
 * It is then impossible to cast the TrLogFactory to the type expected

There's nothing that commons-logging can do to avoid an exception in
this case, except possibly fall back to using the standard
LogFactoryImpl class. However that would be overriding *explicit*
instructions via a system property which isn't something a library
should do lightly.

The solutions are to change the way in which the classes are deployed
instead. In increasing order of complexity:
(a) Don't deploy commons-logging in the webapp at all; it's already
    in the shared classpath. However for most concrete logging
    libraries this means that there's no way to do per-webapp
    logging configuration.
(b) Don't force commons-logging to load its LogFactory implementation
    from the shared classpath. In this case, this means ensuring that
    system property org.apache.commons.logging.LogFactory points to
    an implementation available at the webapp level. The standard
    org.apache.commons.logging.impl.LogFactoryImpl will do for example.
    However this *does* disable whatever functionality was in that
    special IBM class [I've got no idea what TrLogFactory actually
(c) modify the commons-logging.jar file in the webapp to remove the
    LogFactory and Log classes. 
(d) Ensure that class is 
    available in the webapp classloader's path by copying the class
    there. However this might lead to further problems.

In the commons-logging 1.1 release (currently at Release Candidate 5),
file commons-logging-adapters.jar is provided which effectively
implements option (c) above. Using this jar instead of the full
commons-logging.jar should resolve this issue.

Just to recap: the issue is caused by having multiple copies of core
commons-logging classes in the classpath, not by any "bugs" in
commons-logging itself. The fundamental rules of Java classloading
specify that two copies of the same class loaded by two different
classloaders are *not* compatible even when byte-for-byte identical.



To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message