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.

.T.

> -----Original Message-----
> From: Will Jaynes [mailto:[EMAIL PROTECTED]
> Sent: Thursday, October 9, 2003 03:02 PM
> To: [EMAIL PROTECTED]
> 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: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
>



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

Reply via email to