On Sat, 2005-03-19 at 01:32 +1300, Simon Kitching wrote:
> The commons logging wiki FAQ page
> (http://wiki.apache.org/jakarta-commons/Logging/FrequentlyAskedQuestions) has 
> this:
> 
> <extract>
> == Log4JLogger does not implement Log ==
> 
> {{{
> I have an exception with message 'Log4JLogger does not implement Log'!
> What's the cause and how can I fix this problem?
> }}}
> 
> This almost always a classloader issue. Log has been loaded by a
> different classloader from Log4JLogger. Please ensure that:
> 
> * all the logging classes (both Log and the logging implementations) are
> deployed by the same classloader
> * there is only copy of the classes to be found within the classloader
> hierarchy. In application container environments this means ensuring
> that if the classes are found in a parent classloader, they are not also
> present  in the leaf classloader associated with the application. So, if
> the jar is deployed within the root classloader of the container then it
> should be removed from the application's library.
> </extract>

IIRC this is standard advice given scores of times over the years

> I think the last bullet point is too strict; having multiple copies of
> commons-logging.jar should be fine, as long as child-first classloading
> is being used (which it should be). I believe that following this
> recommendation would actually break tomcat 5.x; I believe it *needs*
> commons-logging-api.jar in $CATALINA_HOME/common/lib to operate
> correctly. See: 
>  http://jakarta.apache.org/tomcat/tomcat-5.0-doc/class-loader-howto.html

it is too strict but has emerged as the easiest way for users to solve
their problems without having to analyse classloaders. 

the idea is that you replace the api jar with the full JCL library and
add any log system you want to use (eg Log4J) and then remove all other
JCL jars. this recipe is easy to follow and usually works. 

> Here's my suggested replacement text:
> <text>
> Ensure that both the Log and the Log4JLogger classes used by your
> component (webapp/EJB/other) have been deployed from the same
> classloader. In particular, ensure that commons-logging-api.jar (which
> only provides Log) is not in the path of a classloader which is searched
> "before" a classloader that provides commons-logging.jar (which provides
> both classes). 
> 
> When using a framework that uses standard "child-first" class loading
> order for a component, simply deploying commons-logging.jar in the
> component's private library path (eg WEB-INF/lib) should be sufficient.
> 
> When using a framework that does "parent-first" classloading, it may be
> necessary to replace any copies of commons-logging-api.jar in the
> "shared" libs directory with the full commons-logging.jar (or remove the
> commons-logging-api.jar, though that might have undesirable side-effects
> if it is required by other components or the framework).
> </text>

i'm working on a more detailed troubleshooting document for inclusion in
the standard distribution. (another reason why i haven't rolled another
release candidate.) 

my intention is to pull together various simple recipes (similar to that
given in the wiki) that have helper users over the years and add in more
detailed advanced sections that give some help on the more complex cases
where classloaders have to be considered.

i'm also working on demonstration code inspired by ceki's but
approaching the issues more systematically. i see these two approaches
working in tandem. i've started with the parent first cases. i may
publish when they are finished.

change the wiki if you wish (perhaps considering retaining the recipe in
some form). alternatively, you could wait for the troubleshooting
document.

- robert


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

Reply via email to