Announcement Announcement Module
Collapse
No announcement yet.
Avoid InstanceAlreadyExistsException with Log4J HierarchyDynamicMBean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Avoid InstanceAlreadyExistsException with Log4J HierarchyDynamicMBean

    Hi,
    I want to add the configured loggers of Log4J as MBeans.
    This is working fine, but at star-up it throws a javax.management.InstanceAlreadyExistsException for some patterns layouts.
    I wrote an own class to add my loggers to it with the addLoggerMBean() method of HierarchyDynamicMBean.
    If it adds then the loggers, for the already registered layouts etc. is this exception thrown and logged.
    Is it possible to avoid this, because i want to start the upplication without these worst messages.
    The only chance i see is to reimplement the log4J classes...
    Has someone the same problem?

  • #2
    bump...has anyone fixed this or figured out why this happens, the attribute to ignore exceptions doesn't seem to work? My log4j.xml is located in the ${TOMCAT_HOME}/common/classes directory and not set via dependency injection. Finally, I am using Spring 1.2.7 and viewing the MBeans with MC4J/jconsole.

    Thanks,
    Julian

    Here is my spring config for the log4j and jmx:

    Code:
        <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
            <property name="registrationBehaviorName" value="REGISTRATION_IGNORE_EXISTING"/>
            <property name="beans">
              <map>
                  <entry key="log4j:hiearchy=default" value-ref="hierarchyDynamicMBean"/>
              </map>
            </property>
        </bean>
      
           <bean id="hierarchyDynamicMBean" class="org.apache.log4j.jmx.HierarchyDynamicMBean"/>
    And the error I continue to see:

    Code:
    2006-03-08 19:06:11,717 [main] ERROR org.apache.log4j.jmx.AppenderDynamicMBean.registerLayoutMBean at line ? - Could not add DynamicLayoutMBean for [CONSOLE,layout=org.apache.log4j.PatternLayout].
    javax.management.InstanceAlreadyExistsException: log4j:appender=CONSOLE,layout=org.apache.log4j.PatternLayout
        at com.sun.jmx.mbeanserver.RepositorySupport.addMBean(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.internal_addObject(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(Unknown Source)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(Unknown Source)
        at org.apache.log4j.jmx.AppenderDynamicMBean.registerLayoutMBean(Unknown Source)
        at org.apache.log4j.jmx.AppenderDynamicMBean.preRegister(Unknown Source)
        at com.sun.jmx.mbeanserver.BaseMetaDataImpl.preRegisterInvoker(Unknown Source)
        at com.sun.jmx.mbeanserver.MetaDataImpl.preRegisterInvoker(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(Unknown Source)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(Unknown Source)
        at org.apache.log4j.jmx.LoggerDynamicMBean.registerAppenderMBean(Unknown Source)
        at org.apache.log4j.jmx.LoggerDynamicMBean.appenderMBeanRegistration(Unknown Source)
        at org.apache.log4j.jmx.LoggerDynamicMBean.postRegister(Unknown Source)
        at com.sun.jmx.mbeanserver.BaseMetaDataImpl.postRegisterInvoker(Unknown Source)
        at com.sun.jmx.mbeanserver.MetaDataImpl.postRegisterInvoker(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.internal_addObject(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(Unknown Source)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(Unknown Source)
        at org.apache.log4j.jmx.HierarchyDynamicMBean.addLoggerMBean(Unknown Source)
        at org.apache.log4j.jmx.HierarchyDynamicMBean.postRegister(Unknown Source)
        at com.sun.jmx.mbeanserver.BaseMetaDataImpl.postRegisterInvoker(Unknown Source)
        at com.sun.jmx.mbeanserver.MetaDataImpl.postRegisterInvoker(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.internal_addObject(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(Unknown Source)
        at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(Unknown Source)
        at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(Unknown Source)
        at org.springframework.jmx.export.MBeanExporter.doRegister(MBeanExporter.java:566)
        at org.springframework.jmx.export.MBeanExporter.registerMBean(MBeanExporter.java:485)
        at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:461)
        at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:441)
        at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:368)
        at org.springframework.jmx.export.MBeanExporter.afterPropertiesSet(MBeanExporter.java:312)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1091)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:396)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:233)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:145)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:283)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:313)
        at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.refresh(AbstractRefreshableWebApplicationContext.java:139)
        at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:306)
        at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:251)
        at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:220)
        at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:112)
        at javax.servlet.GenericServlet.init(GenericServlet.java:211)
        at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1091)
        at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:925)
        at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3857)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4118)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
        at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
        at org.apache.catalina.core.StandardService.start(StandardService.java:450)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:683)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:537)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:271)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:409)

    Comment


    • #3
      Why don't you report the problem on the log4j forum/issue tracking? As you said the same name is reused for various log4j components - either the namings should change or the registration should not happen.

      Comment


      • #4
        Costin, I agree something is wrong with the log4j component, but shouldn't the "REGISTRATION_IGNORE_EXISTING" flag set for the MBeanExporter disable these errors from being generated by Spring?

        Julian

        Comment


        • #5
          I haven't checked the source but I think this parameters reffers to the registrations made by the MBeanExporter itself. In this case, from the stacktrace, it seems that the registrations are done by log4j DynamicMBean (which also throws the exception).
          MBeanExporter can't disable these errors (not that it should IMO).

          Comment


          • #6
            Hi,
            I solved this problem in that way by changing the implementation of the log4j jmx components in that way, that this error is catched and then ignored.
            Simple, but not the best way...

            Comment


            • #7
              Here is another way to solve this without overriding all of the log4j jmx classes. All you have to do is temporarily disable the loggers for the jmx classes during the post registration phase.

              Code:
              public class Log4jHierarchyDynamicMBean extends HierarchyDynamicMBean {
              	private List<Logger> loggersToTurnOff = Arrays.asList(
              			new Logger[]{Logger.getLogger(LoggerDynamicMBean.class)
              					, Logger.getLogger(HierarchyDynamicMBean.class)
              					, Logger.getLogger(AppenderDynamicMBean.class)});
              
              	@Override
              	public
              	  void postRegister(java.lang.Boolean registrationDone) {
              		Map<Logger, Level> levels = new HashMap<Logger, Level>(loggersToTurnOff.size());
              		for(Logger logger : loggersToTurnOff)
              		{
              			levels.put(logger, logger.getLevel());
              			logger.setLevel(Level.OFF);
              		}
              		super.postRegister(registrationDone);
              		for(Logger logger : loggersToTurnOff)
              		{
              			levels.put(logger, logger.getLevel());
              			logger.setLevel(levels.get(logger));
              		}
              	  }
              }

              Comment


              • #8
                Originally posted by akarl16 View Post
                Here is another way to solve this without overriding all of the log4j jmx classes. All you have to do is temporarily disable the loggers for the jmx classes during the post registration phase.

                Code:
                public class Log4jHierarchyDynamicMBean extends HierarchyDynamicMBean {
                	private List<Logger> loggersToTurnOff = Arrays.asList(
                			new Logger[]{Logger.getLogger(LoggerDynamicMBean.class)
                					, Logger.getLogger(HierarchyDynamicMBean.class)
                					, Logger.getLogger(AppenderDynamicMBean.class)});
                
                	@Override
                	public
                	  void postRegister(java.lang.Boolean registrationDone) {
                		Map<Logger, Level> levels = new HashMap<Logger, Level>(loggersToTurnOff.size());
                		for(Logger logger : loggersToTurnOff)
                		{
                			levels.put(logger, logger.getLevel());
                			logger.setLevel(Level.OFF);
                		}
                		super.postRegister(registrationDone);
                		for(Logger logger : loggersToTurnOff)
                		{
                			levels.put(logger, logger.getLevel());
                			logger.setLevel(levels.get(logger));
                		}
                	  }
                }
                How to use this ?

                Comment

                Working...
                X