ObjectWeb Consortium
Search ObjectWeb Mail Archive: 

Advanced Search - Powered by Google


Mail Archive Home | architecture List | September 2005 Index

    Date Index  -->     Thread Index  -->

Re: [monolog] LogManager#addLogger breaks classloader isolation (was: Re: Monolog on gcj)



Hi,

The problem is that it is currently impossible to have two copies of
Monolog loaded by two distinct classloaders.  You end up having two
distinct copies of the
org.objectweb.util.monolog.wrapper.javaLog.LoggerFactory class, but
they both talk to the same java.util.logging.LogManager instance.
This leads to Logger instances being shared between two isolating
classloaders.

i ran into this problem in using monolog with oscar. I have a separate copy of the monolog package within each oscar bundle, and I get an error when trying to load the second bundle.

I have implemented a work around, which i submit to your comments. The idea is to isolate the name space of the loggers for each class loader. This is done by prefixing the names with "root#", where # is obtained as the first free name in the shared LogManager. One drawback of this patch is that the changed logger names are visible to the user through the getName() function. I tried to overload it in order to remove the prefix, but it failed due to internal calls to this function by the LogManager.


--
Serge Lacourte
Directeur general
ScalAgent Distributed Technologies SA

*** ref/LoggerFactory.java      Tue Aug 17 09:15:40 2004
--- ./LoggerFactory.java        Wed Sep  7 08:30:57 2005
***************
*** 45,50 ****
--- 45,85 ----
         */
        protected static Logger rootLogger = null;
  
+   private ArrayList loggers = new ArrayList();
+ 
+   /**
+    * Name of the root logger.
+    * This name intends to isolates the loggers associated to a class loader.
+    */
+   protected static String rootLoggerName = null;
+ 
+   /**
+    * Root logger prefix, i.e. <code>rootLoggerName</code> followed by '.'.
+    */
+   protected static String rootLoggerPrefix = null;
+ 
+   /**
+    * Gets the prefix of the root logger.
+    */
+   public static String getRootLoggerPrefix() {
+     return rootLoggerPrefix;
+   }
+ 
+   /**
+    * isolates the logger hierarchy for a given class loader
+    * by prepending the root logger name.
+    *
+    * @param name      user defined name
+    * @return  internal name
+    */
+   protected String monoLoggerName(String name) {
+     if (name.startsWith(rootLoggerPrefix)) {
+       debug("name already prefixed: " + name);
+       return name;
+     }
+     return rootLoggerPrefix + name;
+   }
+ 
      /**
       * This static code initialize the value of the variable defined into
       * BasicLevel.
***************
*** 71,77 ****
          BasicLevel.LEVEL_FATAL = new LevelImpl("FATAL", BasicLevel.FATAL);
  
          manager = LogManager.getLogManager();
!         rootLogger = new Logger(manager.getLogger(""));
      }
  
      /**
--- 106,132 ----
          BasicLevel.LEVEL_FATAL = new LevelImpl("FATAL", BasicLevel.FATAL);
  
          manager = LogManager.getLogManager();
!         String rootName = null;
!         int i = 1;
!       loop_root:
!         while (true) {
!           rootName = "root" + i;
!           synchronized (manager) {
!             // the manager object is shared between the multiple instances 
of this class
!             if (manager.getLogger(rootName) == null) {
!               rootLogger = new Logger(rootName, null);
!               manager.addLogger(rootLogger);
!               rootLogger.setUseParentHandlers(false);
!             }
!           }
!           if (rootLogger != null) {
!             Monolog.debug("Instanciate the root logger " + rootName);
!             break loop_root;
!           }
!           i ++;
!         }
!         rootLoggerName = rootName;
!         rootLoggerPrefix = rootLoggerName + '.';
      }
  
      /**
***************
*** 140,150 ****
--- 195,208 ----
          if (name.equals("root") || name.length()==0) {
              return rootLogger;
          }
+         // isolates the logger hierarchy
+         name = monoLoggerName(name);
          // Search if the logger already exist.
          Object o = manager.getLogger(name);
          if (o == null) {
              // It doesn't exist => creates and adds it
              Logger result = new Logger(name, resName);
+             loggers.add(result);
              Monolog.debug("Instanciate the logger " + name);
              manager.addLogger(result);
              return result;
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.10.18/91 - Release Date: 06/09/2005


    Date Index  -->     Thread Index  -->

Reply via email to:

Powered by MHonArc.

Copyright © 1999-2005, ObjectWeb Consortium | contact | webmaster.