tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Woodchuck <woodchuc...@yahoo.com>
Subject Re: Tomcat 5.5 classloader log4j vs JCL issue
Date Tue, 06 Sep 2005 15:56:24 GMT
hihi Paul,

i tried your suggestion but it still did not work.  however, i finally
found out why.

the problem web application had the following code:

try {
         System.setProperty("org.apache.commons.logging.Log",
                           
"org.apache.commons.logging.impl.Log4JCategoryLog");
      } catch (java.security.AccessControlException e) {
         logCat.warn("Unable map commons-logging to Log4j, due to
SecurityManager",
                     e);
      }

this piece of code seems like the ultimate way of setting the logging
system.  at least this was the effect it had in my case.  (perhaps it
was executed last... definitely after your listener code)

in any case, once i commented out this bit of code everything was fine
again, and i did not have to put the combination log4j.jar and
commons-logging.jar into the ${Tomcat}/common/lib folder.  i was able
to place them in the relevant web app's WEB-INF/lib folder and my other
web apps were undisturbed!  yay!  :)


thanks again for your help, Paul!

woodchuck



--- Paul Austin <mail-lists@revolsys.com> wrote:

> Woodchuck,
> 
> The following web page describes this situation and a solution to the
> problem.
> http://www.qos.ch/logging/sc.jsp
> 
> I have attached the solution that I created this week based on the
> information above. To compile you will need servlet-api.jar and
> log4j.jar to compile.
> 
> Include the jar you create from these files in your web application
> and
> then in your web.xml include the following sections.
> 
> This section can be used if your log4j.xml is not
> under /WEB-INF/log4j.xml
>   <context-param>
>     <param-name>log4jXmlLocation</param-name>
>     <param-value>/WEB-INF/log4j.xml</param-value>
>   </context-param>
> 
> The following calls invokes the listerner when the web app starts up
> to
> create a separate logging context for the web application.
> 
>   <listener>
> 
>
<listener-class>com.revolsys.logging.log4j.Log4jServletContextListener</listener-class>
>   </listener>
> 
> Also make sure you have a listener that does the following when the
> context is destroyed otherwise you'll get a log of PermGen out of
> memory
> errors after a number of redeploys
> 
>         Introspector.flushCaches();
>         LogFactory.getFactory().release();
> 
> Good luck,
> Paul
> 
> On Wed, 2005-08-31 at 13:03 -0700, Woodchuck wrote:
> 
> > hihi all,
> > 
> > on my TC 5.5.9 installation i deployed several web applications
> that
> > uses the default JCL logging.  that is, i placed a simple
> > logging.properties file into each web app's WEB-INF/classes folder
> and
> > i have per web app logging.  everything works beautifully.
> > 
> > then i installed a new web app that forced me to place
> > commons-logging.jar and log4j.jar into the ${Tomcat}/common/lib
> folder.
> >  as a result, all my previous per web app logging no longer works.
> > 
> > i believe this is because log4j was discovered in the
> > ${Tomcat}/common/lib first, and therefore it has superceeded any
> other
> > logging system at the (lower) web app level.  this is due to
> Tomcat's
> > classloading process.
> > 
> > the reason this new web app required commons-logging.jar and
> log4j.jar
> > to be placed specifically into the ${Tomcat}/commons/lib folder is
> > because it instantiates a log4j logger object in it's start-up
> servlet
> > which extends HttpServlet which is found in the servlet-api.jar
> which
> > is also in the ${Tomcat}/commons/lib folder.  this is because
> Tomcat's
> > classloading hierarchy dictates that classes in the common/lib
> cannot
> > see web app classes 'downstream'.
> > 
> > does anyone have any suggestions on how i can have per web app
> logging
> > again?  i would like to keep my deployment process as web app
> isolated
> > as possible (ie. each web app deployed by WAR, drop it in and
> that's
> > it, no further steps necessary).
> > 
> > thanks in advance,
> > woodchuck
> > 
> > 
> > 		
> > ____________________________________________________
> > Start your day with Yahoo! - make it your home page 
> > http://www.yahoo.com/r/hs 
> > 
> > 
> >
> ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail:
> tomcat-user-help@jakarta.apache.org
> > 
> > /*
>  * Copyright 2005 Revolution Systems Inc.
>  * 
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  * 
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  * 
>  * Unless required by applicable law or agreed to in writing,
> software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
>  * See the License for the specific language governing permissions
> and
>  * limitations under the License.
>  */
> package com.revolsys.logging.log4j;
> 
> import java.util.HashMap;
> import java.util.Map;
> 
> import org.apache.log4j.Hierarchy;
> import org.apache.log4j.Level;
> import org.apache.log4j.LogManager;
> import org.apache.log4j.spi.LoggerRepository;
> import org.apache.log4j.spi.RepositorySelector;
> import org.apache.log4j.spi.RootCategory;
> 
> /**
>  * The ContextClassLoaderRepositorySelector class is used to manage
> different
>  * {@link LoggerRepository} heirarchies for different context class
> loaders. The
>  * {@link #add()} method can be used to create a seperate logger
> repository for
>  * the current thread context class loader. When the class loader is
> about to be
>  * destroyed use the {@link #remove()} method to clean up the logger
> repository
>  * for the class loader. See the {@link Log4jServletContextListener}
> for use in
>  * web applications.
>  * 
>  * @author Paul Austin
>  * @version 1.0
>  */
> public class ContextClassLoaderRepositorySelector implements
> RepositorySelector {
>     /** The gaurd used to set the respository selector on the
> LogManager. */
>     private static final Object GUARD = LogManager.getRootLogger();
> 
>     /** The map of class loaders to logging hierarchies. */
>     private static final Map repositories = new HashMap();
> 
>     /**
>      * The deault repository to use when one hasn't been created for
> the class
>      * loader.
>      */
>     private static final LoggerRepository defaultRepository;
> 
>     static {
>         defaultRepository = LogManager.getLoggerRepository();
>         RepositorySelector selector = new
> ContextClassLoaderRepositorySelector();
>         LogManager.setRepositorySelector(selector, GUARD);
>     }
> 
>     /**
>      * Get the logger repository for the current thread context class
> loader or
>      * the default one if one does not exist.
>      * 
>      * @return The logger repository.
>      */
>     public final synchronized LoggerRepository getLoggerRepository()
> {
>         Thread thread = Thread.currentThread();
>         ClassLoader classLoader = thread.getContextClassLoader();
>         Hierarchy hierarchy =
> (Hierarchy)repositories.get(classLoader);
>         if (hierarchy == null) {
>             return defaultRepository;
>         } else {
>             return hierarchy;
>         }
>     }
> 
>     /**
>      * Add a new hierarchy for the current thread context class
> loader if one
>      * does not exist or return the previous hierarchy.
>      * 
>      * @return The created heirarchy.
>      */
>     public static synchronized Hierarchy add() {
>         Thread thread = Thread.currentThread();
>         ClassLoader classLoader = thread.getContextClassLoader();
>         return add(classLoader);
>     }
> 
>     /**
>      * Add a new hierarchy for the specified class loader if one does
> not exist
>      * or return the previous hierarchy.
>      * 
>      * @param classLoader The classloader to create the hierarchy
> for.
>      * @return The created heirarchy.
>      */
>     public static synchronized Hierarchy add(final ClassLoader
> classLoader) {
>         Hierarchy hierarchy =
> (Hierarchy)repositories.get(classLoader);
>         if (hierarchy == null) {
>             hierarchy = new Hierarchy(new
> RootCategory((Level)Level.DEBUG));
>             repositories.put(classLoader, hierarchy);
>         }
>         return hierarchy;
>     }
> 
>     /**
>      * Remove and shutdown the hierarchy for the current thread
> context class
>      * loader class loader.
>      */
>     public static synchronized void remove() {
>         Thread thread = Thread.currentThread();
>         ClassLoader classLoader = thread.getContextClassLoader();
>         remove(classLoader);
>     }
> 
>     /**
>      * Remove and shutdown the hierarchy for the specified class
> loader.
>      * 
>      * @param classLoader The classloader to create the hierarchy
> for.
>      */
>     public static synchronized void remove(final ClassLoader
> classLoader) {
>         Hierarchy hierarchy =
> (Hierarchy)repositories.remove(classLoader);
>         hierarchy.shutdown();
>     }
> 
> }
> > /*
>  * Copyright 2005 Revolution Systems Inc.
>  * 
>  * Licensed under the Apache License, Version 2.0 (the "License");
>  * you may not use this file except in compliance with the License.
>  * You may obtain a copy of the License at
>  * 
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  * 
>  * Unless required by applicable law or agreed to in writing,
> software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
>  * See the License for the specific language governing permissions
> and
>  * limitations under the License.
>  */
> package com.revolsys.logging.log4j;
> 
> import java.io.InputStream;
> 
> import javax.servlet.ServletContext;
> import javax.servlet.ServletContextEvent;
> import javax.servlet.ServletContextListener;
> 
> import org.apache.log4j.Hierarchy;
> import org.apache.log4j.xml.DOMConfigurator;
> 
> /**
>  * The Log4jServletContextListener class uses the
>  * {@link ContextClassLoaderRepositorySelector} to maintain a
> separate Log4j
>  * configuration for a servlet context and to load the logging
> configuration
>  * from the log4j.xml file specified by the log4jXmlLocation
> context-param (or
>  * /WEB-INF/log4j.xml if not specified).
>  * 
>  * @author Paul Austin
>  * @version 1.0
>  */
> public class Log4jServletContextListener implements
> ServletContextListener {
>     /** The default location for the log4j.xml file. */
>     public static final String DEFAULT_LOG4J_XML_LOCATION =
> "/WEB-INF/log4j.xml";
> 
>     /**
>      * Initialize the logging for context by creating a new heirarchy
> for the
>      * current thread context class context and loading the
> configuration from
>      * the log4jXmlLocation context-param.
>      * 
>      * @param event The servler context event.
>      */
>     public void contextInitialized(ServletContextEvent event) {
>         Hierarchy hierarchy =
> ContextClassLoaderRepositorySelector.add();
>         ServletContext context = event.getServletContext();
>         String log4jXml =
> context.getInitParameter("log4jXmlLocation");
>         if (log4jXml == null) {
>             log4jXml = DEFAULT_LOG4J_XML_LOCATION;
>         }
>         try {
>             InputStream log4JConfig =
> context.getResourceAsStream(log4jXml);
>             if (log4JConfig != null) {
>                 DOMConfigurator conf = new DOMConfigurator();
>                 conf.doConfigure(log4JConfig, hierarchy);
>             }
>         } catch (Exception e) {
>             throw new RuntimeException(e);
>         }
>     }
> 
>     /**
>      * Clean up the context by removing the logging configuration for
> the
>      * current context.
>      * 
>      * @param event The servler context event.
>      */
>     public void contextDestroyed(ServletContextEvent event) {
>         ContextClassLoaderRepositorySelector.remove();
>     }
> 
> }
> 
> >
---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-user-help@jakarta.apache.org



	
		
______________________________________________________
Click here to donate to the Hurricane Katrina relief effort.
http://store.yahoo.com/redcross-donate3/

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org


Mime
View raw message