Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 16898 invoked from network); 10 Oct 2003 17:26:40 -0000 Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12) by minotaur-2.apache.org with SMTP; 10 Oct 2003 17:26:40 -0000 Received: (qmail 57318 invoked by uid 500); 10 Oct 2003 17:26:28 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 57266 invoked by uid 500); 10 Oct 2003 17:26:28 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 57252 invoked from network); 10 Oct 2003 17:26:27 -0000 Received: from unknown (HELO webmail.speakeasy.net) (216.254.0.84) by daedalus.apache.org with SMTP; 10 Oct 2003 17:26:27 -0000 Received: (qmail 3949 invoked from network); 10 Oct 2003 17:26:31 -0000 Received: from localhost (HELO webmail4) ([127.0.0.1]) (envelope-sender ) by localhost (qmail-ldap-1.03) with SMTP for ; 10 Oct 2003 17:26:31 -0000 Received: from 170.186.245.65 (unverified [170.186.245.65]) by webmail4 (VisualMail 4.0) with WEBMAIL id 2563; Fri, 10 Oct 2003 17:26:31 +0000 From: "Todd Jonker" To: "Jakarta Commons Developers List" Importance: Normal Sensitivity: Normal Message-ID: X-Mailer: Mintersoft VisualMail, Build 4.0.111601 X-Originating-IP: [170.186.245.65] Date: Fri, 10 Oct 2003 17:26:31 +0000 Subject: Re: commons-logging & classloading Reply-to: tvj@pobox.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Will, I'm curious: Why do you have commons-logging at both the server AND= web-app levels? It seems to me that if you only put it at the server le= vel then all the apps will use the same logging framework. That's what I= 'm doing currently. .T. > -----Original Message----- > From: Will Jaynes [mailto:jaynes@umich.edu] > Sent: Friday, October 10, 2003 04:59 PM > To: 'Jakarta Commons Developers List' > Subject: Re: commons-logging & classloading > > I was hoping some developers would weigh in on this issue. I expect tha= t > this has been discussed before, but I can't find any references. > > I believe the classloading in commons-logging is broken. The web app us= e > case I describe below is a demonstration of why c-l is broken. The way = > classloading is implemented makes it impossible to to share components = > at the J2EE server level. It's clear from looking at the > LogFactory.getContextClassLoader() method that the developers explicitl= y > want to use the thread context classloader. But it just causes problems= . > > I went in and changed LogFactory.getContextClassLoader() to simply > return LogFactory.class.getClassLoader(), and all my logging problems > went away. I can put slide, HttpClient, commons-logging at the server > level; and struts, commons-logging, log4j in the web apps. And things > work fine and just as I expect them to. > > So, can someone please explain why commons-logging is implemented as it= > is? Will anyone consider changing it? > > Thanks, Will > > Will Jaynes wrote: > > > >> 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 p= er > > >webapp (pointing at the classes in /WEB-INF/classes and /WEB-INF/li= b), > > >plus normally a parent class loader for shared classes and resource= s. > > >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 t= heir > > >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-loggin= g. > > 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 ap= p > > levels? > > > > So far, nothing works properly unless all components are at the web a= pp > > 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. (b= y > > the way, I'm using Java 1.4) > > > > As soon as my web app trys to use HttpClient I get a exception : "Cla= ss > > org.apache.commons.logging.impl.Log4JLogger does not implement Log". = I > > believe that what is happening is this: HttpClient loads with the ser= ver > > classloader. HttpClient wants to log, so it causes Log and LogFactory= to > > be loaded with the server classloader. LogFactory specifically uses t= he > > 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, b= ut > > 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 ap= p. > > Commons-loggin has made it impossible to deploy slide and HttpClie= nt > > 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 > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org > For additional commands, e-mail: commons-dev-help@jakarta.apache.org > > > --------------------------------------------------------------------- To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org For additional commands, e-mail: commons-dev-help@jakarta.apache.org