2 Replies Latest reply on Jan 15, 2009 11:21 AM by Mauro Molinari

    JBoss JTA and the logging system: using system properties

    Mauro Molinari Novice

      Hello there!
      Today I found another thing that makes embedding JBossJTA into a multi-application environment a bit tricky.

      When a TransactonalDriver instance is created (or, whenever a jdbcLogger.logger.isDebugEnabled() call is made), the static initialization of jdbc logger is performed and this eventually causes a call to com.arjuna.common.util.logging.LogFactory.setupLogSystem(). This method reads jbossjta-properties.xml and then sets the system property org.apache.commons.logging.Log to the appropriate implementation class name. However, this has implications on all the other applications that use Commons Logging and that may start AFTER the one using JBossJTA.

      To be more specific: we're deploying JBossJTA together with our webapp on a Tomcat server. If our webapp is not the last one to be started by Tomcat AND our webapp causes the JBossJTA logging system to be initialized (using Log4j) BEFORE one of the remaining webapp is started, if one of these use Commons Logging but does not come with Log4j it will fail to start becaue its call to org.apache.commons.logging.LogFactory.getLog(String) causes org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(String) to try to load the Log4j implementation as one of its first choices.

      Specifically, suppose the ordering in which Tomcat starts the webapps is the following:
      - tomcat manager
      - our webapp
      - the root webapp

      The root webapp failes to start unless Log4j is deployed with Tomcat.

      Workarounds:
      - forcing Tomcat to load our webapp as the last one
      - put Log4j JAR in Tomcat server libs
      - change JBossJTA configuration to use JDK logger, but this is a problem since all our application logging is done through Log4j and this, in any case, would force other webapps to use the JDK logger

      All workarounds have drawbacks.

      Any hint to solve this problem is welcome. Is there any way to avoid JBossJTA to change the system properties?

      Mauro.

        • 1. Re: JBoss JTA and the logging system: using system propertie
          Jonathan Halliday Master

          This is basically JBTM-325 and stems from commons logging braindead use of what are essentially global variables. Have you tried bundling commons logging with the app, which should cause it to be loaded from the webapp classloader rather than tomcat and thus have its own local config?

          • 2. Re: JBoss JTA and the logging system: using system propertie
            Mauro Molinari Novice

             

            "jhalliday" wrote:
            This is basically JBTM-325 and stems from commons logging braindead use of what are essentially global variables. Have you tried bundling commons logging with the app, which should cause it to be loaded from the webapp classloader rather than tomcat and thus have its own local config?


            Commons logging is bundled with my app, but not with the other apps (like ROOT) that fail to start.
            After new tests I see that I must deploy both commons-logging and log4j to Tomcat common lib, but in this way I need to configure log4j for the whole Tomcat to avoid to loose log messages because of a "log4j not configured problem".

            At the end, the workaround I did is the following:

            final String logSystemPropertyValue =
             System.getProperty(LogFactoryImpl.LOG_PROPERTY, null);
             jdbcLogger.logger.isDebugEnabled();
             if(logSystemPropertyValue == null)
             System.clearProperty(LogFactoryImpl.LOG_PROPERTY);
             else
             System.setProperty(LogFactoryImpl.LOG_PROPERTY, logSystemPropertyValue);
            


            This code is expecuted early in my webapp initialization. In this way, subsequent use of the jdbcLogger.logger does not cause the system property to be set and other apps can start after mine with no problem.

            I know it's ugly...

            Mauro.