commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Todd Jonker" <>
Subject Re: commons-logging & classloading
Date Thu, 09 Oct 2003 16:19:31 GMT
Will, I recently ran into a variant of this, only worse.

We solved the problem by placing log4j in the system classpath, so it's shared by all applications,
and by all server-level components.

We are using an oldish version of WebLogic, with ColdFusion MX running inside of it.  ColdFusion
has an evil webservices.jar file that includes a PRE-1.0 version of commons-logging.  We had
to move webservices.jar up to the server level as well to insure that the current version
of JCL is used in all applications.

I think the best solution would be a JCL configuration option that caused it to ignore the
thread-context classloader.


> -----Original Message-----
> From: Will Jaynes []
> Sent: Thursday, October 9, 2003 03:02 PM
> To:
> Subject: Re: commons-logging & classloading
>  >> 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:
> For additional commands, e-mail:

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

View raw message