On Tue, 2005-07-26 at 09:49 -0700, Mark Palmer wrote:
> I have written a open source version of jta for tomcat
> that can be used with and the existing version of
> apache DBCP. (to be released shortly)
>
> I am using log4j of course:-)
>
> My code and needs to be common/lib (i.e. don't want to
> modify the web application war file in any way)
>
> This means log4j needs to be in common/lib as well.
>
> However some of the web application are bundled with
> log4j.
>
> As a result I get:
>
> log4j:ERROR [StandardClassLoader
> delegate: true
> repositories:
> file:C:\tomcat\common\classes\
>
> ----------> Parent Classloader:
> [EMAIL PROTECTED]
> ] whereas object of type
> log4j:ERROR "org.apache.log4j.RollingFileAppender" was
> loaded by [WebappClassLoader
> delegate: false
> repositories:
> /WEB-INF/classes/
> ----------> Parent Classloader:
> StandardClassLoader
> delegate: true
> repositories:
> file:C:\tomcat\\classes\
> ----------> Parent Classloader:
> StandardClassLoader
> delegate: true
> repositories:
> file:C:\tomcat\common\classes\
> ...
>
> Any ideas on how to get around this class loader
> issue?
>
> I don't mind writer some custom log4j code to help
You appear to have omitted the previous three error messages which are
extremely important to understanding the meaning of this one.
After some investigation made trickier by this omission, it appears that
the message is coming from log4j's
OptionConverter.instantiateByClassname method.
I expect that the full messages are complaining about
RollingFileAppender not being compatible with type Appender.
The cause of this is the helpers.Loader class looking in the thread
context classloader (TCL aka TCCL) to find classes whose names are in
the log4j.properties or log4j.xml file. It finds a class of the
requested name, but that class is bound to the Appender class loaded
from the TCCL not from the one that the calling class has bound to.
Are you or the container using the Contextual Repository Selector? I'm
presuming not. In this case, log4j is actually going to get initialised
just once - and this will happen the first time any log4j method is
called. It's doubly-bad therefore when that first call happens in the
context of *some arbitrary* webapp, and that log4j's Loader class then
tries to load classes whose names are in the log4j configuration file
from that arbitrary webapp.
If you could ensure that log4j was initialised before any webapp tries
to call it that would fix the problem. Putting a call to a log4j method
in the static initialiser of one of your classes might be worth trying:
class SomeClass {
static {
// force log4j initialisation outside of the context of a webapp
Logger.getLog("");
}
}
however that relies on something causing that class to be loaded.
Maybe you could write a Tomcat "valve" class that gets put into the
tomcat configuration file that has the dummy static block. Valves should
get loaded on tomcat startup. Anyway, there's bound to be some variant
of that idea that works.
Regards,
Simon
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]