commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Will Jaynes <jay...@umich.edu>
Subject Re: commons-logging & classloading
Date Thu, 09 Oct 2003 15:02:25 GMT
 >> Why does LogFactoryImpl in commons-logging
 >> try to load the Log implementation class first
 >> from thread classloader and then loader that loaded this class?
 >>
 >> Is there some kind of design pattern behind this?
 >>
 >
 >One very common :-) use case for commons-logging is inside web
 >applications, where the servlet container provides a class loader per
 >webapp (pointing at the classes in /WEB-INF/classes and /WEB-INF/lib),
 >plus normally a parent class loader for shared classes and resources. 
  >The container is required to set the Thead context class loader for the
 >current webapp prior to handing the request off to the servlet.
 >
 >The lookup design pattern in LogFactoryImpl allows webapps to use their
 >own version of the log implementation classes.

With regard to this web app use case, the problem I'm seeing is that I 
can't share components at the server level if they use commons-logging. 
What must the configuration of jars and property files look like if I 
have components that use commons-loggin both at the server and web app 
levels?

So far, nothing works properly unless all components are at the web app 
level (in WEB-INF/lib).


Here's an example of what can go wrong:
I have slide and HttpClient in at the server level in resin/lib. 
HttpClient uses commons-logging, so I have to add commons-logging to 
resin/lib. My web app uses Struts, so I've got commons-logging in 
WEB-INF/lib, and I use log4j, so log4j.jar is also in WEB-INF/lib. (by 
the way, I'm using Java 1.4)

As soon as my web app trys to use HttpClient I get a exception : "Class
org.apache.commons.logging.impl.Log4JLogger does not implement Log". I 
believe that what is happening is this: HttpClient loads with the server 
classloader. HttpClient wants to log, so it causes Log and LogFactory to 
be loaded with the server classloader. LogFactory specifically uses the 
thread context classloader to look a log factory. The thread context 
classloader is the web app's classloader, so it finds LogFactoryImpl and 
log4j and then loads Log4JLogger, but it is still using the thread 
context classloader, so it finds the Log4JLogger in the WEB-INF/lib. It 
then does a check with Log.class.isAssignableFrom() on Log4JLogger, but 
since Log and Log4JLogger were loaded with different classloaders the 
test fails and the exception is thrown.

After a lot of experimentation, the only configuration of jars that 
works properly is to put everything in the WEB-INF/lib of each web app. 
    Commons-loggin has made it impossible to deploy slide and HttpClient 
at the server level.

Am I missing something in how to configure this use case?

Will


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message