4 Replies Latest reply on May 20, 2009 9:19 AM by sstacha

    Web Application Context Logging (log4j) Question

    sstacha

      I have been trying to implement a context listener that will allow me to have different repositories for each web application that is deployed. I was using several examples that I googled and keep getting java Verify errors. When tailoring it down line by line I finally got the following:


      java.lang.LinkageError: loader constraints violated when linking org/apache/log4j/Level class
      at org.apache.log4j.spi.WebAppRepositorySelector.init(WebAppRepositorySelector.java:36)
      at biz.ormia.util.logging.ContextRepositoryListener.contextInitialized(ContextRepositoryListener.java:40


      I intend to post more detailed code and such but I was wondering what is the appropriate forum to post this question to for the best response?

      OS: OSX 10.5 (on intel mac)
      jboss: 4.2.1 GA & 5.0.1 GA


      Thanks,

      steve

        • 1. Re: Web Application Context Logging (log4j) Question
          jaikiran

          This is the right forum :)

          Are you packaging any log4j jars with your application?

          • 2. Re: Web Application Context Logging (log4j) Question
            sstacha

            Yes, I include log4j-1.2.8 in each webapp's WEB-INF/lib folder. Let me go ahead and post the background code and such then.

            First, I was trying to load a context event listener with the following code:

            package biz.ormia.util.logging;

            /**
            * User: sstacha
            * Date: May 3, 2009
            * Time: 1:22:11 PM
            * Attempt to do logging without much effort on the devleopers part.
            * Developers will need to add the following the web.xml file
            *
            * <listener-class>biz.ormia.util.logging.ContextRepositoryListener</listener-class>
            *
            *
            */

            import org.apache.log4j.spi.WebAppRepositorySelector;

            import javax.servlet.ServletContextEvent;
            import javax.servlet.ServletContextListener;
            import java.util.Enumeration;

            public class ContextRepositoryListener implements ServletContextListener
            {
            public void contextInitialized(ServletContextEvent contextEvent)
            {
            try
            {
            System.out.println("Attempting to add a context to the repositorySelector: " + contextEvent.getServletContext().getServletContextName());
            Enumeration names=contextEvent.getServletContext().getAttributeNames();
            System.out.println("----- attributes -----");
            String name;
            while (names.hasMoreElements())
            {
            name = (String)names.nextElement();
            System.out.println(" " + name + " - " + contextEvent.getServletContext().getAttribute(name));
            }
            names=contextEvent.getServletContext().getInitParameterNames();
            System.out.println("----- init params -----");
            while (names.hasMoreElements())
            System.out.println(" " + names.nextElement());
            WebAppRepositorySelector.init(contextEvent.getServletContext());

            //ContextRepositorySelector.init(contextEvent.getServletContext());

            }
            catch (Exception ex) {System.err.println(ex);}
            }

            public void contextDestroyed(ServletContextEvent contextEvent)
            {
            System.out.println("Attempting to remove a context from the repositorySelector: " + contextEvent.getServletContext());
            ContextRepositorySelector.removeContext();
            }
            }


            As you can see mostly I was trying to figure out what I had available to me and make sure it was being called. The only real thing in init is to call the
            WebAppRepositorySelector.init(contextEvent.getServletContext());
            WebAppRepositorySelector is my implementation which simply tries to take the default respository that jboss sets up and then tries to add a new one for each webapp deployment.

            package org.apache.log4j.spi;

            import org.apache.log4j.LogManager;
            import org.apache.log4j.Hierarchy;

            import javax.servlet.ServletContext;
            import javax.servlet.ServletException;
            import java.util.Map;
            import java.util.HashMap;

            /**
            * User: sstacha
            * Date: May 5, 2009
            * Time: 2:58:16 PM
            * To change this template use File | Settings | File Templates.
            */
            public class WebAppRepositorySelector implements RepositorySelector
            {
            private static Map<ClassLoader, LoggerRepository> repositories = new HashMap<ClassLoader, LoggerRepository>();
            private static LoggerRepository defaultRepository;

            public static void init(ServletContext context) throws ServletException
            {
            System.out.println("in addContext...");
            System.out.println("current thread: " + Thread.currentThread().getName());
            System.out.println("classloader: " + Thread.currentThread().getContextClassLoader().toString());
            System.out.println("context: " + context.getServletContextName());
            if (defaultRepository == null)
            {
            defaultRepository = LogManager.getLoggerRepository();
            Object guard = LogManager.getRootLogger();
            LogManager.setRepositorySelector(new WebAppRepositorySelector(), guard);
            }
            System.out.println("defaultRepository: " + defaultRepository.toString());

            org.apache.log4j.Logger rootLogger = new RootLogger(org.apache.log4j.Level.DEBUG);
            System.out.println("rootLogger: " + rootLogger);
            // org.apache.log4j.Hierarchy hierarchy = new Hierarchy(rootLogger);
            //
            // try {repositories.put(Thread.currentThread().getContextClassLoader(), hierarchy);}
            // catch (Exception ex) {System.out.println("Exception while creating new heiarchy for repository: " + ex);}
            // if (defaultRepository == null)
            // {
            // defaultRepository = LogManager.getLoggerRepository();
            // Object guard = LogManager.getRootLogger();
            // LogManager.setRepositorySelector(new CTXRepositorySelector(), guard);
            // }
            // // add our thread instance in for lookup later
            // Hierarchy hierarchy = new Hierarchy(new RootLogger(Level.DEBUG));
            // try {repositories.put(Thread.currentThread().getContextClassLoader(), hierarchy);}
            // catch (Exception ex) {System.out.println("Exception while creating new heiarchy for repository: " + ex);}
            }

            public static synchronized void removeContext()
            {
            System.out.println("in removeContext...");
            System.out.println("current thread: " + Thread.currentThread().getName());
            System.out.println("classloader: " + Thread.currentThread().getContextClassLoader().toString());
            }


            private WebAppRepositorySelector() { }

            public LoggerRepository getLoggerRepository()
            {
            System.out.println("in getLoggerRepository...");
            System.out.println("current thread: " + Thread.currentThread().getName());
            System.out.println("classloader: " + Thread.currentThread().getContextClassLoader().toString());
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            // Hierarchy hierarchy = (Hierarchy) repositories.get(cl);
            //
            // if (hierarchy == null) {
            // hierarchy = new Hierarchy(new RootLogger(org.apache.log4j.Level.DEBUG));
            // hierMap.put(cl, hierarchy);
            // }
            //
            // return hierarchy;
            LoggerRepository repository = null;
            try
            {
            repository = repositories.get(Thread.currentThread().getContextClassLoader());
            }
            catch (Exception ex) {System.out.println("Exception in getLoggerRepository getting the repository from the class loader: " + ex);}
            if (repository == null)
            {
            System.out.println("respository is null using default...");
            return defaultRepository;
            }
            else
            {
            System.out.println("Using repository: " + repository);
            return repository;
            }
            // if (repository == null)
            // return defaultRepository;
            // return repository;
            // if (defaultRepository != null)
            // return defaultRepository;
            // return null;
            }
            }


            Note that this works as I have it commented here but I am not doing anything aside from saving off the original jboss repository and then resetting the selector to ourselves. If I uncomment the next line:

            org.apache.log4j.Hierarchy hierarchy = new Hierarchy(rootLogger);

            Then I get the error mentioned above. If I don't put my Selector in the log4j...spi package then I get a generic error:

            [ERROR] - Exception sending context initialized event to listener instance of class biz.ormia.util.logging.ContextRepositoryListener
            java.lang.VerifyError: (class: biz/ormia/util/logging/ContextRepositorySelector, method: init signature: (Ljavax/servlet/ServletContext;)V) Incompatible argument to function

            • 3. Re: Web Application Context Logging (log4j) Question
              sstacha

              So, given the lack of responses... How are others dealing with having custom logging levels for multiple deployed applications?

              Is there an easier way to pass a custom RepositorySelector via a parameter at startup or something?

              • 4. Re: Web Application Context Logging (log4j) Question
                sstacha

                No one else has this problem or does custom logging for each application?