Announcement Announcement Module
Collapse
No announcement yet.
ClassPathXmlApplicationContextMBean? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • ClassPathXmlApplicationContextMBean?

    Hello

    I'm using JBoss and want to expose some Spring-JMX exported beans to the JBoss MBean server. Following the simple example in the JBoss developer guide, I've written a SpringContainerMBean, which simply allows a ClasspathXMLApplicationContext to be created from a list of resource locations - all the further work is done in the applicationContext.xml.

    In JBoss, all that then has to be done is create a SAR, exploded or otherwise, to get JBoss to load up things at startup in a manner that's similar to the mechanism used for Web apps.

    Surely someone's written something like this before? It would be really handy to have a generic bootstrapping MBean which can create it's own application context.

  • #2
    A few weeks ago I had a similar idea. But, instead, I wanted to expose an application context via an MBean, then all the beans in the context could be accessed via something like JConsole in Java 5.0. I never looked any further into it.

    Seemed like a useful idea. For example, though the bean config files declare something, only the running app will show what really got wired together. Scrutinizing log files is so 1980's.

    -- J. Betancourt

    Comment


    • #3
      I've extended what I'd written to do this by programmatically using a Spring exporter in the MBean used by JBoss to publish the application context itself as an MBean under a configurable JNDI name.

      You do get a list of the number of beans avaiable, their names, etc. Looks kind of cool, the way a lot of things do when viewed in a JMX view, but I'm not sure if this is what you were really looking for.

      Were you looking for something that would allow you to explore the instantiated object graph? Not sure how you'd acheive this...

      Comment


      • #4
        Originally posted by timothygordon32
        Were you looking for something that would allow you to explore the instantiated object graph? Not sure how you'd acheive this...
        That and more.

        Comment


        • #5
          Hi,

          Im learning about Spring with JBoss....
          Im searching for examples of Jboss and spring integration.
          I need expose the ApplicationContext through of MBean
          to use in the application server.

          Can You post some examples here? :oops:

          thank u very much

          Comment


          • #6
            Hi,

            I'm a newbie too and I don't know where I find about how use this functionality. It's confused yet for me.

            thanks

            Comment


            • #7
              This is the MBean interface for the JBoss bootstrapper:

              Code:
              package com.allustra.test.jmx;
              
              /**
               * @author timg
               * @Copyright (c) Allustra Ltd. 2005.  All rights reserved.
               */
              public interface SpringContainerMBean
              {
                /**
                 * Setter for the JNDI name under which the application context will be exported as an MBean.
                 * @param applicationContextJndiName The JNDI name.
                 */
                void setApplicationContextJndiName(String applicationContextJndiName);
              
                /**
                 * Getter for the JNDI name under which the application context will be exported as an MBean.
                 * @return The JNDI name.
                 */
                 String getApplicationContextJndiName();
              
                /**
                 * Setter for the resource locations of the XML-based Spring configuration file(s).
                 * @param locations The resource locations in the classpath.
                 */
                void setConfigLocations(String[] locations);
              
                /**
                 * Getter for the resource locations of the XML-based Spring configuration file(s).
                 * @return The resource locations in the classpath.
                 */
                String[] getConfigLocations();
              
                /**
                 * JMX lifecycle method.
                 * @throws Exception
                 */
                void start() throws Exception;
              
                /**
                 * JMX lifecycle method.
                 * @throws Exception
                 */
                void stop() throws Exception;
              }
              This is the implementation:

              Code:
              package com.allustra.test.jmx;
              
              import java.util.Map;
              import java.util.HashMap;
              
              import org.apache.commons.logging.Log;
              import org.apache.commons.logging.LogFactory;
              import org.springframework.context.ApplicationContext;
              import org.springframework.context.support.ClassPathXmlApplicationContext;
              import org.springframework.beans.factory.DisposableBean;
              import org.springframework.jmx.export.MBeanExporter;
              
              /**
               * @author timg
               * @Copyright (c) Allustra Ltd. 2005.  All rights reserved.
               */
              public class SpringContainer implements SpringContainerMBean
              {
                protected final Log m_logger = LogFactory.getLog(getClass());
              
                private String[] m_configLocations;
                private String m_applicationContextJndiName;
                private ApplicationContext m_context;
                private MBeanExporter m_exporter;
              
                public void setApplicationContextJndiName(String applicationContextJndiName)
                {
                  m_applicationContextJndiName = applicationContextJndiName;
                }
              
                public String getApplicationContextJndiName()
                {
                  return m_applicationContextJndiName;
                }
              
                public void setConfigLocations(String[] locations)
                {
                  if (locations != null)
                  {
                    m_configLocations = new String[locations.length];
                    System.arraycopy(locations, 0, m_configLocations, 0, locations.length);
                  }
                  else
                  {
                    m_configLocations = null;
                  }
                }
              
                public String[] getConfigLocations()
                {
                  String[] result = null;
              
                  if (m_configLocations != null)
                  {
                    result = new String[m_configLocations.length];
                    System.arraycopy(m_configLocations, 0, result, 0, m_configLocations.length);
                  }
                  return result ;
                }
              
                public void start() throws Exception
                {
                  if (!isStarted())
                  {
                    if (m_logger.isInfoEnabled())
                    {
                      m_logger.info("SpringContainer starting...");
                    }
              
                    if (m_configLocations != null)
                    {
                      m_context = new ClassPathXmlApplicationContext(m_configLocations);
                      if (m_applicationContextJndiName != null)
                      {
                        m_exporter = new MBeanExporter();
                        Map beans = new HashMap();
                        beans.put(m_applicationContextJndiName, m_context);
                        m_exporter.setBeans(beans);
                        m_exporter.afterPropertiesSet();
                      }
              
                      if (m_logger.isInfoEnabled())
                      {
                        m_logger.info("SpringContainer started");
                      }
                    }
                    else
                    {
                      if (m_logger.isInfoEnabled())
                      {
                        m_logger.info("SpringContainer - no config locations, not started");
                      }
                    }
                  }
                }
              
                private boolean isStarted()
                {
                  return m_context != null;
                }
              
                public void stop() throws Exception
                {
                  if (isStarted())
                  {
                    if (m_logger.isInfoEnabled())
                    {
                      m_logger.info("SpringContainer stopping...");
                    }
              
                    if (m_context instanceof DisposableBean)
                    {
                      ((DisposableBean)m_context).destroy();
                    }
                    m_context = null;
              
                    if (m_exporter instanceof DisposableBean)
                    {
                      ((DisposableBean)m_exporter).destroy();
                    }
                    m_exporter = null;
              
                    if (m_logger.isInfoEnabled())
                    {
                      m_logger.info("SpringContainer stopped");
                    }
                  }
                }
              }
              You'll need this in addtion to any beans you'd like to expose via JMX:

              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
              <beans>
                <bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter">
                  <property name="beans">
                    <map>
                      <entry key="allustra&#58;service=PersonGreeter"><ref bean="personGreeter"/></entry>
                    </map>
                  </property>
                </bean>
              </beans>
              Where personGreeter is just some noddy class I wrote to demo the concept - it'd defined in another applicationContext.xml which need know nothing about your JMX stuff.

              And then your jboss-service.xml will need to look something like:
              Code:
              <!-- The SAR META-INF/jboss-service.xml descriptor -->
              <server>
                <mbean code="com.allustra.test.jmx.SpringContainer"
                       name="allustra&#58;service=TestSpringContainer">
                  <attribute name="ConfigLocations">
              com/allustra/test/applicationContext.xml
              com/allustra/test/jmx/applicationContext-jmx.xml
                  </attribute>
                  <attribute name="ApplicationContextJndiName">allustra&#58;service=TestApplicationContext</attribute>
                </mbean>
              </server>
              Knock yourselves out.

              Comment


              • #8
                thanks...

                I found the source of net.sf.hibernate.jmx.HibernateService
                and I create similir your code.

                But, How can I find the JNDI name correct?

                thanks again

                Comment


                • #9
                  Hmmm. Not entirely sure what you're asking, but its made me realise I've made a small mistake here.

                  The applicationContextJndiName should really read applicationContextObjectName. It's the ObjectName that the application context will be listed under when you view the MBeans via the Agent View in the JBoss JMX console. If you don't supply it in the jboss-service.xml, then the application context itself will not be registered as an MBean.

                  If you're asking about JNDI then I'm assuming you're wanting to access the MBean programatically. Inside the JBoss JVM you could probably do this using the MBean server. If you're looking to do this remotely then you'll need to go through the RMI adapter. Sun has a tutorial on all this, and Spring provides facilities to create a plain Java proxy to a remote MBean - see the PDF documentation.

                  Comment


                  • #10
                    Hi :-)

                    Well, I get the ApplicationContext created in start up using JNDI.
                    I use a Plugin of Struts and I try to get the ApplicationContext like this:

                    Code:
                    			InitialContext ctx = new InitialContext&#40;&#41;; 
                    			
                    			this.wac = &#40;WebApplicationContext&#41; ctx.lookup&#40;"java&#58;/SpringAppContextJndi"&#41;;
                    
                    			context.setAttribute&#40;APPLICATION_CONTEXT, this.wac&#41;;
                    I saw the JNDI view and Its not created a jndi for applicationContext.

                    Ive added the bellow code to bind a Jndi to context in the
                    start() method:

                    Code:
                    					JndiTemplate jndiTemplate = new JndiTemplate&#40;&#41;;
                    					
                    					jndiTemplate.bind&#40;this.jndiName, this.appContext&#41;;
                    but the applicationContext does not serializable.

                    What Can I do about this?

                    thanks![/code]

                    Comment

                    Working...
                    X