Discussions

News: Setting up JMX ManagedBeans in Spring

  1. Setting up JMX ManagedBeans in Spring (19 messages)

    Craig Walls, XDoclet in Action, Spring in Action, has written about the Spring-JMX module that currently sits in the sandbox. He walks us through how we can setup our Spring components as JMX MBeans, and other Spring-JMX features.

    Excerpt
    The next thing I did was declare this bean in my Spring configuration file:

      <bean id="managedBean"
          class="com.habuma.jmx.ManagedBeanImpl">
        <property name="someProperty"><value>Howdy</value></property>
      </bean>

    Again, nothing too special. Just a regular Spring bean declaration.

    But here's where the JMX stuff starts. I declared the following bean:

      <bean id="jmxAdapter"
          class="org.springframework.jmx.JmxMBeanAdapter"
          depends-on="jmxServer"
          >
        <property name="beans">
          <map>
          <entry key="foobar:Name=myBean">
              <ref bean="managedBean"/>
            </entry>
          </map>
        </property>
      </bean>

    JmxMBeanAdapter takes a java.util.Map of bean references and exposes their properties and methods as managed properties and managed operations of an MBean...automagically. The key of each map entry is used to create the ObjectName.
    Read Craig talk about Spring JMX in: Playing in the Spring sandbox

    Threaded Messages (19)

  2. Interesting article (though I haven't had time to play with it yet), how would you regsiter the beans in an existing server like JBoss? Can it use a static reference to the MBeanServer?

    Whats the release data for Spring 1.2? Also, will JMS consumers also be included in the same release?
  3. Graham,

    Not too sure on the 1.2 release date, we have some interesting features planned for that release so I guess we'll know better once 1.1 is out officially.

    By default the JmxMBeanAdapter (British spelling - sorry!) will look for an MBeanServer in the VM. JBoss has this already so it should pick it up, although I have not yet tested this since all development has been against 1.2 RI.

    Rob
  4. Great stuff, Rob. This is the yet-to-be-realesed part of Spring that I am most excited about. I also have a question for you...

    What about having an easy way to expose *all* beans, or at least a subset of all beans in an ApplicationContext through JMX? From what I can tell, you have to explicitly register every bean you want managed in the <beans> map of the JmxMBeanAdapter bean, correct?

    It would be cool to have a bean similar to the DefaultAdvisorAutoProxyCreator. Basically, you would configure a bean that would go out and expose other beans in the ApplicationContext as managed beans. This could be based on type, name, a combination of both, whatever. I guess this could have a pluggable naming strategy, but using the bean's "Spring" name makes the most sense in this case, right? For example, to make all MVC Controller's managed:

    <bean class="org.springframework.jmx.AutoJmxConfigurer" depends-on="jmxServer>
        <property name="type">
            <value>org.springframework.web.servlet.mvc.Controller</value>
        </property>
    </bean>

    Basically, the AutoJmxConfigurer could instantiate a JmxMBeanAdapter under the covers and be responsible for configuring the JmxMBeanAdapter Map of managed beans. Perhaps the AutoJmxConfigurer could also have a "namespace" property to use when assigning managed bean names.

    Perhaps this could also make use of the ClassFilter class? Although that does not feel quite right to me. Basically, I am wanting a way to expose managed beans without having to explicitly naming them. Perhaps there is already a way and I have just totally missed the boat. If so, please ignore this :-)

    Ryan
  5. Ryan,

    That is a cracking idea! It will go hand in hand with the plans to create a way to centrally define a management interface for many different bean of different concrete types. Consider a situation where you have an intferace Foo and then maybe three of four implementations that are active in your application. You want to expose all four beans to JMX but only the methods in the Foo interface. I have plans for allowing this to be done using XML and Java interfaces, but with your AutoConfigurer idea it would be trivial to register all beans of type Foo.

    I will start on this once I have finished up on the JmxProxyFactoryBean.

    Rob
  6. Setting up JMX ManagedBeans in Spring[ Go to top ]

    What I thought would be a good idea would be to use a mix of AOP and source-level metadata to decide what beans are exposed as MBeans. You can already use source-level metadata in the MBean naming strategy and to decide which attributes/operations are exposed. Why not extend that to also decide which beans are MBeans? In this case, the pointcut would match when a bean has a certain attribute that indicates it is an MBean. Whatdya think?
  7. Right. Before, I was thinking of filtering managed beans at a class level, but I suppose you need to filter at a method level. This would be a perfect fit for a Pointcut. Going back to my earlier example...

    <bean class="org.springframework.jmx.AutoJmxConfigurer" depends-on="jmxServer>
        <property name="pointcut"><ref bean="myJmxPointcut"/></property>
        <property name="namespace"><value>MyApp</value></property>
    </bean>

    The AutoJmxConfigurer would scour the ApplicationContext and find beans whose method(s) match the given Pointcut and then expose these beans (and the matched methods) as MBeans.
  8. Craig/Ryan,

    Interesting suggestions - I wonder if it might just simpler to run through all beans and see if they have the ManagedResource attribute, if so I can use the rest of the metadata on the bean to create them mgmt interface. Essentially I would an new interface such as AutodectingMetadataAssembler. The JMXMBeanAdapter will, if its metadata assembler implements this, give it a chance to locate additional beans other than those specified explicitly. In this way you would simply define the adapter bean, the metadata assembler beans and your application beans. The adapter bean and metadata bean will automatically locate any beans that have the ManagedResource attribute and expose them as JMX beans.

    rob
  9. Setting up JMX ManagedBeans in Spring[ Go to top ]

    This works for me.
  10. non-standard[ Go to top ]

    Ryan,

    While this sounds extremely useful and powerful I question how 'standard' this approach is.

    What you've suggested is an alternative approach to managing beans, totally circumventing the JMX standard approach which requires your bean to implement some sort of *MBean interface.

    Sounds like you just want the ability to define pointcuts which Spring will use to reflect against every bean within an ApplicationContext and expose them as Managed Beans.

    Great idea but very un-JMX-like from my understanding.
  11. non-standard[ Go to top ]

    Wayland,

    The JMX standard defines the ModelMBean interface for this very reason - to allow management interface metadata to be defined dynamically rather than statically. Note that in no way does the JMX standard require your beans to implement a *MBean interface. The StandardMBean allows for exposure of beans based on JavaBean style naming conventions, and ModelMBean is used to wrap a bean that has not defined its management interface and to generate this interface dynamically.

    Rob
  12. oops[ Go to top ]

    Ryan,

    My apologies but I just realized that your approach might be totally valid when applied to the 'Model MBean' standard.
  13. oops[ Go to top ]

    Ryan,My apologies but I just realized that your approach might be totally valid when applied to the 'Model MBean' standard.
    Ah, you guys beat me to the punch.
  14. non-standard[ Go to top ]

    Further to my previous post, JMX is all about managing your application, not about constraining you to write beans in a particular way. The JMX team knew that many different frameworks would want to simplify the exposure of beans to MBeanServers and thus created the ModelMBean interface.

    In no way does Spring JMX 'totally circumvent the JMX standard approach'. It uses standard JMX interfaces that are supported in all JMX implementations.
  15. RequredModelMBean[ Go to top ]

    Rob,

    How are we handling the case where we might want to leverage the RequiredModelMBean class provided by a specific JMX implementation? I know the spec requires that all JMX implementations provide that class; and some may provide custom support for interpreting descriptors in regard to persistence, security, remoting, other kinds of things. Would it be possible to use a default implementation, and simply configure it to use the metadata definition (ModelMBeanInfo) that specifies everything you need to map to the target object (and the info object could be built using a variety of strategies, eg. pulling from the db, annotations, config file, etc.)? What does having different mbean invocation strategies e.g reflection vs cglib for target object access buy you?

    Great work btw!
  16. RequredModelMBean[ Go to top ]

    Keith,

    That is certainly possible, and I had considered that as the first option. The only problem that I saw was that many of the implementations, the RI, included, have an error in the code for removing attribute change notification listeners. I can add in an option to force Spring to use the RequiredModelMBean, that should be trivial but I want to keep the custom ModelMBean to give us full flexibility.

    The use of multiple invocation strategies is simply for flexibility. It allows us to improve the performance of invocations as new improvements appear in proxying and reflection techniques. In the short term I would recommend everyone use the Cglib invoker since it is a bit faster than the JDK one, especially if you are running on a 1.3 JVM.

    Rob
  17. Non-standard[ Go to top ]

    Spring's JmxMBeanAdapter uses an implementation of the javax.management.modelmbean.ModelMBean interface. How I understand it, the ModelMBean interface is used to create MBeans that wrap non-JMX beans, making them managable. The methods that are managable are determined by an instance of ModelMBeanInfo that is passed to the ModelMBean.

    By default, Spring uses a ModelMBeanInfo implementation that detemermines the managed methods using reflection. This makes *all* methods managed (I believe). This could be replaced by an attribute driven implementation that makes methods managed based on their meta-data.

    To sum all this up - Spring *is* doing JMX in a standard, albeit dynamic, fashion. Muy, muy cool if you ask me.

    Ryan
  18. Non-standard[ Go to top ]

    Spring's JmxMBeanAdapter uses an implementation of the javax.management.modelmbean.ModelMBean interface. How I understand it, the ModelMBean interface is used to create MBeans that wrap non-JMX beans, making them managable. The methods that are managable are determined by an instance of ModelMBeanInfo that is passed to the ModelMBean.By default, Spring uses a ModelMBeanInfo implementation that detemermines the managed methods using reflection. This makes *all* methods managed (I believe). This could be replaced by an attribute driven implementation that makes methods managed based on their meta-data.To sum all this up - Spring *is* doing JMX in a standard, albeit dynamic, fashion. Muy, muy cool if you ask me.Ryan
    Yes. That's right for the default implementation, but you have the choice (by plugging another implementation in your Spring config xml file):
    - JDK 1.5 annotations
    - Apache Commons Annotations (works in JDK 1.4)
    - Interface based (you define a Java interface and it exports the methods from that interface, the bean is not forced to implement the interface and you can even use multiple interfaces (comma separated in the Spring config xml file).
    - You explicitly name the methods to export in the spring config xml file
    - ...
  19. Since the release candidate of 1.2 is already out so there is a bit of difference in the declaration of an MBean as follows.
    <bean id="jmxAdaptor" class="org.springframework.jmx.export.MBeanExporter">
    <property name="beans">
    <map>
    <entry key="foobar:Name=myBean">
    <ref local="managedBean"/>
    </entry>
    </map>
    </property>
    </bean>
  20. mBeanServer naming[ Go to top ]

    FYI: I also had to change the name from mBeanServer to beanServer in the HtmlAdapterFactoryBean class and in the jmx-app.xml to avoid an exception: "org.springframework.beans.NotWritablePropertyException: Invalid property 'mBeanServer' of bean class [HtmlAdapterFactoryBean]"

    I'm new to Spring, so I could have a configuration problem.

    Overall, this was a pretty neat application demonstrating JMX support within Spring. =)