On Wed, 2005-05-18 at 12:20 +0200, David Perez wrote: > You're right, I have changed the commons-logging version to the latest one. > Now I have reverted to commons-logging-1.0.2
I would recommend using commons-logging-1.0.4. After all, that is the most recent official release. > >I suggest registering a ServletContextListener. Declare a <listener> > >element in the web.xml file, with a nested <listener-class> element > >containing the fully qualified classname of a logging-cleanup class. In > >the contextDestroyed method of that class do this: > > * LogFactory.release( > > Thread.currentThread().getContextClassLoader()) > > * somehow cleaning up the underlying logging library if needed. > > > >If that doesn't help, let me know and we can look into it a bit > >further. > > > > > From my code I call LogFactory.releaseAll() after removing the old web > app context, and no luck :-( Do you mean that you use a ServletContextListener as I described? Or something else? Note also that LogFactory.releaseAll may not do what you want. If your webapp has bound to commons-logging that is loaded via a shared classloader, then calling releaseAll will shut down *all* instances of commons-logging - which other webapps running in the same container may not appreciate :-). The code I recommended will only shut down logging for the webapp whose context is being destroyed, assuming you are calling the method from a SerletContextListener.contextDestroyed, ie from code where Thread.currentThread.getContextClassLoader() returns the classloader of the webapp being unloaded. > Should my webapp use another copy of commons-logging.jar? That depends. If your webapp has all the libraries it needs in WEB-INF/lib, then yes. Deploying commons-logging.jar in WEB-INF/lib in that situation makes things very clean and consistent. There's no need to use call LogFactory.release() in this case, as undeploying the webapp automatically undeploys commons-logging and the underlying logging lib. But if your webapp is calling into code that is deployed via a shared classloader, and that code uses commons-logging, then you must *not* also deploy commons-logging in WEB-INF/lib. If you do (and you are using release 1.0.4), you will get the message Invalid class loader hierarchy. You have more than one version of org.apache.commons.logging.Log visible, which is not allowed. If you are using an earlier release, you will probably get something like: AvalonLogger does not implement Log > Here is the logging jars I use in my app: > > jars used by the web server (Jetty): > > * commons-logging.jar and > * log4j.jar > > jars used by the webapp: > > * logkit.jar > > My web app uses Cocoon which uses Avalon LogKit, and makes me > include logkit.jar, even though logging is redirected to log4j. What do you mean "logging is redirected to log4j"? > Some other classes use directly commons-logging > > With commons-logging-1.0.4 and 1.05 alpha1, I have to make logkit.jar > available to Jetty, otherwise commons-loggings throws a > ClassNotFoundException, because it cannot find > > org/apache/log/Hierarchy. I wonder why it tries to load LogKit if Log4j is > already available? Commons-logging does *not* auto-discover LogKit; it doesn't even try. So somewhere something in your webapp must be *ordering* commons-logging to use AvalonLogger (aka LogKit) as the logger. Which logging lib commons-logging uses can be explicitly set via a number of methods; .properties files, jdk1.3 service files, system properties. See the commons-logging documentation for more information. > Caused by: java.lang.NoClassDefFoundError: org/apache/log/Hierarchy > at > org.apache.commons.logging.impl.LogKitLogger.getLogger(LogKitLogger.java:77) > at > org.apache.commons.logging.impl.LogKitLogger.<init>(LogKitLogger.java:64) > at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) > at > sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) > at > sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) > at java.lang.reflect.Constructor.newInstance(Constructor.java:494) > at > org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:529) Yep, commons-logging's LogFactoryImpl is explicitly trying to instantiate a LogKitLogger object. Can you please: (a) look for what is ordering commons-logging to use LogKit and remove that? (b) use commons-logging 1.0.4; I will be able to help you much better than if you use the very old 1.0.2. Also, can you please confirm that Jetty (and your webapp) use the standard child-first (aka parent-last) classloading order? I know the Resin webserver doesn't, and that makes things quite different... And by the way, where do you put your log4j configuration file? Good luck! Simon --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
