9 Replies Latest reply on Oct 28, 2010 8:55 AM by alesj

    How to force log4j.xml to be read out of my war?

    phyto

      Hi folks,

       

      Here's my problem, i have a WAR within an EAR.  Within the EAR itself are all the jars used by the WAR, which has no jars.  My WAR does log4j logging, and contains a log4j.xml in it's WEB-INF/classes.  The problem is, several of the jars in the EAR have also package a log4j.xml within them and the classloader is preferring these inner log4j.xmls to the one in my WAR's WEB-INF/classes.   I should mention that the WAR declares a manifest.mf file that lists the jars in the EAR explicitly.

       

      I think I've confirmed this theory (of the EAR's resources being preffered over WEB-INF/classes), by the following:  I moved all the libs out of the EAR into the WAR's WEB-INF/lib.  My logging works in this case, as I would expect, since WARs honor resources in 'classes' over 'lib'. 

       

      I'd like to keep the jars in the EAR and not have to move them to the WAR.   I have tried listing the log4j.xml in the WAR's manifest ahead of all other resources, but that does not work.  I have also tried twiddling the jboss-classloading.xml to get around this, to no avail.  Any ideas?

       

      For a little more context, see http://goo.gl/kNqn

       

      Thanks!

      Aaron

        • 1. Re: How to force log4j.xml to be read out of my war?
          alesj

          Hmm, it should go to local CL resources first.

          See the "trail" from BaseClassLoader::getResource --> BaseClassLoaderDomain::getResource.

           

          Could you debug it a bit?

           

          ---

           

          URL getResource(BaseClassLoader classLoader, String name, boolean allExports)
             {
                boolean trace = log.isTraceEnabled();

           

                // Try the classloader first
                if (classLoader != null)
                {
                   if (trace)
                      log.trace(this + " trying to get resource " + name + " from requesting " + classLoader);
                   URL result = classLoader.getResourceLocally(name); // <--- locally
                   if (result != null)
                   {
                      if (trace)
                         log.trace(this + " got resource from requesting " + classLoader + " " + result);
                      return result;
                   }
                }

           

                if (getClassLoaderSystem() == null)
                   throw new IllegalStateException("Domain is not registered with a classloader system: " + toLongString());

           

                // Try the before attempt
                URL result = beforeGetResource(name); // <--- check parent here
                if (result != null)
                   return result;

          • 2. Re: How to force log4j.xml to be read out of my war?
            phyto

            I'd be happy to debug this further.  Can you point me to the source that you are referencing here?  I turn on trace logging for this class and see what that tells me.

            • 3. Re: How to force log4j.xml to be read out of my war?
              alesj

              Can you point me to the source that you are referencing here?

              BaseClassLoader and BaseClassLoaderDomain, both are in jboss-classloader.jar.

              * http://anonsvn.jboss.org/repos/jbossas/projects/jboss-cl/trunk/classloader/src/main/java/org/jboss/classloader/spi/base/

              1 of 1 people found this helpful
              • 4. Re: How to force log4j.xml to be read out of my war?
                phyto

                Now I'm really confused.  Seems according to the trace output that the correct log4j.xml is being loaded..

                 

                2010-10-26 10:46:56,791 TRACE [org.jboss.classloader.spi.base.BaseClassLoader] (main) BaseClassLoader@78618ac5{vfsfile:/opt/jboss-5.1.0.GA/server/default/deploy/pentaho.ear/pentaho.war/} getResource log4j.xml domain=ClassLoaderDomain@30e6ace7{pentaho.war}
                2010-10-26 10:46:56,791 TRACE [org.jboss.classloader.spi.base.BaseClassLoaderDomain] (main) ClassLoaderDomain@30e6ace7{pentaho.war} trying to get resource log4j.xml from requesting BaseClassLoader@78618ac5{vfsfile:/opt/jboss-5.1.0.GA/server/default/deploy/pentaho.ear/pentaho.war/}
                2010-10-26 10:46:56,791 TRACE [org.jboss.classloader.spi.base.BaseClassLoader] (main) BaseClassLoader@78618ac5{vfsfile:/opt/jboss-5.1.0.GA/server/default/deploy/pentaho.ear/pentaho.war/} get resource locally log4j.xml
                2010-10-26 10:46:56,797 TRACE [org.jboss.classloader.spi.base.BaseClassLoader] (main) BaseClassLoader@78618ac5{vfsfile:/opt/jboss-5.1.0.GA/server/default/deploy/pentaho.ear/pentaho.war/} got resource locally log4j.xml
                

                 

                Now I am lost as to why log4j is acting as if it has been given a different config.  I need to think of a way of isolating this to show exactly what's happening.

                Thanks for you help, Ales!

                • 5. Re: How to force log4j.xml to be read out of my war?
                  phyto

                  hmm, perhaps the log4j.xml file mentioned in these trace message is actually coming from a jar and now WEB-INF/classes.  Not sure how I can know that

                  • 6. Re: How to force log4j.xml to be read out of my war?
                    alesj
                    Now I am lost as to why log4j is acting as if it has been given a different config.  I need to think of a way of isolating this to show exactly what's happening.

                    Perhaps too much static behavior in log4j?

                    e.g. class is loaded by JBoss CL, keeping this logging config/info, hence ignoring yours

                    (i'm just guessing, as i never really looked deep into log4j ...)

                    • 7. Re: How to force log4j.xml to be read out of my war?
                      alesj

                      hmm, perhaps the log4j.xml file mentioned in these trace message is actually coming from a jar and now WEB-INF/classes.  Not sure how I can know that

                      Which jar? ear's jar?

                      ear's top level classlaoder should be different then war's cl

                      WEB-INF/lib is scanned for resources later then WEB-INF/classes -- by the spec -- if you mean those lib jars

                      • 8. Re: How to force log4j.xml to be read out of my war?
                        phyto

                        (just saw your latest comment, I am talking about EAR jars)

                         

                        From similar trace methods, I see that resources known to be embedded within EAR-level jars are logged similarly as being found in the WAR classloader.  My question now is, should I expect a WAR within an EAR to have a child CL?  I think what I may be seeing is, there is just one CL for an EAR.  In other words, I'm wondering if my local WEB-INF/classes/log4j.xml is not being found because the WAR does not have it's own CL, but shares it with the EAR.  Here is my war's jboss-classloading.xml, I am even being explicit about searching the WAR domain first

                        <classloading xmlns="urn:jboss:classloading:1.0"
                          name="pentaho.war"
                          domain="pentaho.war"
                          parent-domain="pentaho.ear"
                          export-all="NON_EMPTY"
                          import-all="true"
                          parent-first="false">
                        </classloading>
                        
                        • 9. Re: How to force log4j.xml to be read out of my war?
                          alesj
                          My question now is, should I expect a WAR within an EAR to have a child CL? 

                          Yes.

                          I think what I may be seeing is, there is just one CL for an EAR.

                          You can check the jmx-console for classloaders. Check if there are two or just one for your deployment.

                          I'm wondering if my local WEB-INF/classes/log4j.xml is not being found because the WAR does not have it's own CL, but shares it with the EAR.

                          Where are your log4j classes? Does war have it's own copy of log4j?

                          Here is my war's jboss-classloading.xml, I am even being explicit about searching the WAR domain first

                          This config is already done by default for .war deployments.

                          See WarClassLoaderDeployer class in JBossAS.