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

  • JMX Notification Listener

    I have a spring 2.5.6 application. The app uses HornetQ to send JMS messages to a topic consumer in a separate app. I have a timertask that periodically sends a "heartbeat" message on the JMS topic. In the same app, I also have a jmx managed bean and a jmx notification listener. My goal is to have the jmx notification listener send a message to the JMS topic whenever an attribute is changed.

    The issue is that the handleNotification() method of my jmx listener cannot seem to access the class which sends the jms message (called JmsTopicSender). If I try to call jmsTopicSender.sendMessage(userdataobj) using the property in the class, nothing happens. However, if I do:

    JmsTopicSender s = appContext.getBean("jmsTopicSender");
    s.sendMessage(userdataobj);

    the message is sent perfectly.

    I don't understand why the listener doesn't have access to attributes in the class. Can someone help explain??

    Here's the relevant part of my context file:
    Code:
    <bean id="exporter"
         class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter"
         lazy-init="false">
        <property name="notificationListenerMappings">
          <map>
            <entry key="*">
              <bean class="cloud.gm.ingest.file.HealthMonitor"/>
            </entry>
          </map>
        </property>
      </bean>
    
     <!-- Set up to use the default mbean server -->
        <context:mbean-server/>
        
        <bean  id="healthMonitor" class="cloud.gm.ingest.file.HealthMonitor">
            <property name="jmsTopicSender" ref="jmsTopicSender" />
        </bean>
    ...
        <!-- Create the topic for sending the heartbeat messages. -->
        <bean id="heartbeatTopic" class="org.hornetq.api.jms.HornetQJMSClient" factory-method="createTopic">
            <constructor-arg index="0" value="infrastructure.heartbeat"/>
        </bean>
      
        <!-- JMS Template -->
        <bean id="jmsTemplate"
            class="org.springframework.jms.core.JmsTemplate">
         <property name="connectionFactory" ref="cachedConnectionFactory"></property>
        </bean>
    
        <!-- Bean to send JMS messages -->
        <bean id="jmsTopicSender" class="cloud.gm.ingest.file.JmsTopicSender">
            <property name="jmsTemplate" ref="jmsTemplate" />
            <property name="destination" ref="heartbeatTopic"/>
        </bean>

    and the HealthMonitor code is:

    Code:
    public class HealthMonitor implements NotificationListener, NotificationFilter {
        private static final long serialVersionUID = 1L;
        private static final Logger logger = LoggerFactory.getLogger( HealthMonitor.class );
        private DataFlowController dataFlowController;
        private JmsTopicSender jmsTopicSender;
        
        public void setDataFlowController(DataFlowController dataFlowController){
            this.dataFlowController = dataFlowController;
        }
        
        public void setJmsTopicSender(JmsTopicSender jmsTopicSender) {
            this.jmsTopicSender = jmsTopicSender;
        }
            
        //called by timertask
        public void checkHeartbeat() {
            logger.debug("checkHeartbeat... - Thread:  " + Thread.currentThread().getName());
            try {
                //this.jmsTopicSender.sendMessage("this is a string.");
                this.jmsTopicSender.sendHeartbeatMessage(this.dataFlowController.isAvailable());
            } catch (JMSException e) {
                // TODO Auto-generated catch block
                logger.info("coulndn't do send", e);
                e.printStackTrace();
            }
            logger.info("finished checkHeartbeat...");
        }
        
        public void handleNotification(Notification notification, Object handback) {
            logger.info("Received notification from " + notification.getSource());
            try {
                logger.info("sending message with message = " + notification.getUserData());
                this.jmsTopicSender.sendMessage((String)notification.getUserData());
            } catch (JMSException e) {
                // TODO Auto-generated catch block
                logger.info("coulndn't do send", e);
                e.printStackTrace();
            }
            logger.info("finished handleNotification()");
           
        }
    
        public boolean isNotificationEnabled(Notification notification) {
            return AttributeChangeNotification.class.isAssignableFrom(notification.getClass());
        }
        
    }
    When an attribute is changed, the log file shows the message "sending message with message = ...", but nothing after it. The very first line in the jmsTopicSender.sendMessage() method is a log message and it is not getting recorded.

    Code:
    2011-11-10 09:05:55,281 INFO  HealthMonitor - Received notification from spring:name=dataFlowController:  
    2011-11-10 09:05:55,281 INFO  HealthMonitor -  user data = an attribute has changed
    2011-11-10 09:05:55,281 INFO  HealthMonitor - sending message with message = an attribute has changed
    2011-11-10 09:06:39,911 DEBUG HealthMonitor - checkHeartbeat...
    2011-11-10 09:06:39,911 INFO  JmsTopicSender - heartbeat::: sending message to infrastructure.heartbeat
    2011-11-10 09:06:39,911 DEBUG JmsTemplate - Executing callback on JMS Session: Cached JMS Session: HornetQRASession->org.hornetq.core.client.impl.DelegatingSession@185c0de
    2011-11-10 09:06:39,911 INFO  JmsTopicSender - Sending heartbeat ...
    2011-11-10 09:06:39,911 DEBUG JmsTemplate - Sending created message: HornetQMessage[null]:PERSISTENT
    2011-11-10 09:06:39,911 INFO  JmsTopicSender - heartbeat:::  done sending message to infrastructure.heartbeat
    2011-11-10 09:06:39,911 INFO  HealthMonitor - finished checkHeartbeat...
Working...
X