Spring Framework
  1. Spring Framework
  2. SPR-6851

autodetect of jmx mbeans either doesn't work, or not like the doc describes

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Invalid
    • Affects Version/s: 2.5.6
    • Fix Version/s: None
    • Component/s: JMX
    • Labels:
      None
    • Last commented by a User:
      true

      Description

      I've been experimenting with trying to enable autodetection of JMX mbeans in my Spring context. Although I've had no trouble explicitly listing my mbeans in the "beans" property in the context, that's not quite optimal. I'm seeing more issues than the subject line describes, but I think they are issues with interpreting how this thing is supposed to work. It could be that all of the issues I'm seeing are just documentation problems, but I can't tell for certain.

      I'm using the @Managed... annotations in the bean class to specify the JMX attributes. I'd prefer to have them there than in the context. The only one that's somewhat questionable is the mbean name. I think I would want to set the "name=" part, but not the part before it (I'm not certain what the JMX-specific terms are for those pieces). For instance, in my class I currently have:

      objectName = "springjmxbug:name=logBean"

      it seems reasonable to set "logBean" in the class, but I think "springjmxbug" would be better set in the context.

      Despite the other questions about how this is supposed to work, in my testing, I've been unable to find an arrangement where autodetection will work, but it's entirely possible I'm misinterpreting how it's supposed to work.

      For instance, here's a short excerpt from my context:
      ----------------
      <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
      <property name="assembler" ref="assembler"/>
      <property name="autodetect" value="true"/>
      <property name="beans">
      <map>
      <entry key="springjmxbug:name=logBean" value-ref="logManager"/>
      </map>
      </property>
      </bean>
      <bean id="logManager" class="springjmxbug.Log4JManager"/>
      <bean id="attributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>

      <bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
      <property name="attributeSource" ref="attributeSource"/>
      </bean>
      ----------------

      Here's my "Log4JManager" class:
      ----------------------
      @ManagedResource(objectName = "springjmxbug:name=logBean", description = "Bean for controlling Log4J levels in DynamicContent")
      public class Log4JManager {
      @ManagedOperation(description = "Set a Log4J logging level for a specific category (package)")
      @ManagedOperationParameters(

      { @ManagedOperationParameter(name = "packageName", description = "Log4J category name"), @ManagedOperationParameter(name = "level", description = "Log4J level") }

      )
      public void setLogLevel(String packageName, String level)

      { LogManager.getLogger(packageName).setLevel(Level.toLevel(level)); }

      @ManagedOperation(description = "Get a Log4J logging level for a specific category (package)")
      @ManagedOperationParameters(

      { @ManagedOperationParameter(name = "packageName", description = "Log4J category name") }

      )
      public String getLogLevel(String packageName)

      { return LogManager.getLogger(packageName).getLevel().toString(); }

      }
      --------------------

      If I comment out the "beans" property, I get this very confusing error message:

      "Unable to register MBean [springjmxbug.Log4JManager@1ad637e] with key 'logManager'; nested exception is javax.management.MalformedObjectNameException: Key properties cannot be empty"

      Looking at the section in the doc that covers this, there is the following example:
      -----------------------
      <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
      <property name="autodetect" value="true"/>
      </bean>
      <bean name="spring:mbean=true" class="org.springframework.jmx.export.TestDynamicMBean"/>
      -----------------------

      There are a couple of confusing elements here. First, "autodetect" is set to true, but right there is the definition of the bean. If this is what is intended, then the meaning of "autodetect" is very different from what it means in the rest of Spring. Second, the definition of this bean using class "org.springframework.jmx.export.TestDynamicMBean" is odd, as there's no such class.

      I'm attaching a Maven project that I've been using to demonstrate these issues.

        Activity

        David M. Karr created issue -
        Hide
        David M. Karr added a comment -

        Run "mvn install" after unpacking and deploy the resulting WAR file to test it.

        Show
        David M. Karr added a comment - Run "mvn install" after unpacking and deploy the resulting WAR file to test it.
        David M. Karr made changes -
        Field Original Value New Value
        Attachment springjmxbug.zip [ 16203 ]
        Trevor Marshall made changes -
        Workflow jira [ 30449 ] SPR Workflow [ 40220 ]
        Dave Syer made changes -
        Assignee Dave Syer [ david_syer ]
        Hide
        Dave Syer added a comment -

        The MBeanExporter is trying to use its default naming strategy which doesn't know about your @ManagedResource. If you want to configure the MBeanExporter as an explicit bean definition like that, you need to provide a ObjectNamingStrategy as well (e.g. use the MetadataNamingStrategy in your case). Alternatively, you can use the <context:mbean-export/> short cut.

        The user guide has examples of both explicit bean definitions and the short cut I think.

        Show
        Dave Syer added a comment - The MBeanExporter is trying to use its default naming strategy which doesn't know about your @ManagedResource. If you want to configure the MBeanExporter as an explicit bean definition like that, you need to provide a ObjectNamingStrategy as well (e.g. use the MetadataNamingStrategy in your case). Alternatively, you can use the <context:mbean-export/> short cut. The user guide has examples of both explicit bean definitions and the short cut I think.
        Dave Syer made changes -
        Resolution Invalid [ 6 ]
        Status Open [ 1 ] Resolved [ 5 ]
        Hide
        David M. Karr added a comment -

        If someone is running into an issue similar to this, I think I discovered something that clears this up.

        I think the combination of a "@ManagedResource"-annotated class and a "context:mbean-export" element in the context will result in Spring automatically exporting that class as a JMX MBean, but ONLY if there is an explicit bean definition in the context, or more reasonably, if you also add a "@Component" annotation to the annotated class.

        I think the point is that "@ManagedResource" will cause the bean associated with this class to be exported, but only if the bean exists, and "@ManagedResource" is not like "@Component", "@Service", et cetera, which will be found when "context:component-scan" is used.

        So, the conclusion is that you need both "@Component" and "@ManagedResource" on a class if you don't have it otherwise specified as a bean in the context.

        Show
        David M. Karr added a comment - If someone is running into an issue similar to this, I think I discovered something that clears this up. I think the combination of a "@ManagedResource"-annotated class and a "context:mbean-export" element in the context will result in Spring automatically exporting that class as a JMX MBean, but ONLY if there is an explicit bean definition in the context, or more reasonably, if you also add a "@Component" annotation to the annotated class. I think the point is that "@ManagedResource" will cause the bean associated with this class to be exported, but only if the bean exists, and "@ManagedResource" is not like "@Component", "@Service", et cetera, which will be found when "context:component-scan" is used. So, the conclusion is that you need both "@Component" and "@ManagedResource" on a class if you don't have it otherwise specified as a bean in the context.
        Trevor Marshall made changes -
        Workflow SPR Workflow [ 40220 ] New SPR Workflow [ 62386 ]
        Trevor Marshall made changes -
        Workflow New SPR Workflow [ 62386 ] SPR Workflow [ 71844 ]
        Transition Time In Source Status Execution Times Last Executer Last Execution Date
        Open Open Resolved Resolved
        298d 19h 27m 1 Dave Syer 12/Dec/10 3:58 AM

          People

          • Assignee:
            Dave Syer
            Reporter:
            David M. Karr
            Last updater:
            Trevor Marshall
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              2 years, 17 weeks, 1 day ago