Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@www.apache.org Received: (qmail 72686 invoked from network); 10 Oct 2003 19:31:47 -0000 Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12) by minotaur-2.apache.org with SMTP; 10 Oct 2003 19:31:47 -0000 Received: (qmail 9825 invoked by uid 500); 10 Oct 2003 19:31:21 -0000 Delivered-To: apmail-jakarta-commons-dev-archive@jakarta.apache.org Received: (qmail 9785 invoked by uid 500); 10 Oct 2003 19:31:21 -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 9737 invoked from network); 10 Oct 2003 19:31:20 -0000 Received: from unknown (HELO talus) (141.214.40.231) by daedalus.apache.org with SMTP; 10 Oct 2003 19:31:20 -0000 Received: from umich.edu (host-74.subnet-172.med.umich.edu [141.214.172.74]) by talus.msis.med.umich.edu (iPlanet Messaging Server 5.2 HotFix 1.10 (built Jan 23 2003)) with ESMTPSA id <0HMK00HIC3L8ST@talus.msis.med.umich.edu> for commons-dev@jakarta.apache.org; Fri, 10 Oct 2003 15:31:56 -0400 (EDT) Date: Fri, 10 Oct 2003 15:31:25 -0400 From: Will Jaynes Subject: Re: commons-logging & classloading In-reply-to: To: Jakarta Commons Developers List Message-id: <3F87090D.6030205@umich.edu> MIME-version: 1.0 Content-type: text/plain; charset=us-ascii; format=flowed Content-transfer-encoding: 7BIT X-Accept-Language: en-us, en User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.5) Gecko/20030925 References: 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 Todd, I put c-l at the server and web app levels because that's how I could get it to work (and only with my changed version). I've tried *every* configuration of jar files and the *only* thing that works is if I put all jars into each WEB-INF/lib. Please remember that all was well with me until I tried putting HttpClient.jar (which uses commons-logging) at the server level. That's when I began experiencing problems. Before I tried adding HttpClient.jar to the server level, I lived happily with commons-logging and log4j in each web app. Each web app had it's own log4j.properties and was independent of all other web apps. Life was good. Will Todd Jonker wrote: > 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 level 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 >> that this has been discussed before, but I can't find any >> references. >> >> I believe the classloading in commons-logging is broken. The web >> app use 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 explicitly 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 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 >>> >> >> >> --------------------------------------------------------------------- >> 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