In my previous post I described how to pause message delivery in WebSphere. Today I am going to show how to pause message delivery in JBoss. The technique is the same. Obtain MBean that control's a Queue or Topic and invoke methods on it. Alternatively in JBoss you can go to JMX Console:
  1. Go to http://localhost:8080/jmx-console
  2. Locate the Message Driven Bean and click on it. This takes you to MDB's MBean view
  3. Use startDelivery() or stopDelivery() to control message flow.
Following is a class that controls message delivery programmatically.
/**
 * @(#)DeliveryControl.java	Mar 25, 2008
 */
package com.ksi.demo.console;

import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.jboss.ejb.plugins.jms.JMSContainerInvokerMBean;
import org.jboss.mx.util.MBeanProxy;
import org.jboss.mx.util.MBeanProxyCreationException;
import org.jboss.mx.util.MBeanServerLocator;

/**
 * Control Message Delivery in JBoss.
 */
public class DeliveryControl {
	private static final int START = 1;
	private static final int STOP = 0;

	/**
	 * @see com.allstream.icms.core.jmx.JMXSupplement#startMessageDelivery(javax.management.ObjectName)
	 */
	public void startMessageDelivery(ObjectName mbeanName) {
		invokeMethodOnJMSContainer(mbeanName, START);
	}

	/**
	 * @see com.allstream.icms.core.jmx.JMXSupplement#stopMessageDelivery(javax.management.ObjectName)
	 */
	public void stopMessageDelivery(ObjectName mbeanName) {
		invokeMethodOnJMSContainer(mbeanName, STOP);
	}

	protected void invokeMethodOnJMSContainer(final ObjectName objectName, final int method) {
		try {
            // Another way to locate JBoss MBeanServer
			/**
			Properties props = new Properties();
			props.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
			props.put(InitialContext.PROVIDER_URL, "jnp://localhost:1099");
			props.put(InitialContext.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
			InitialContext iniCtx = new InitialContext(props);
			MBeanServer mbeanServer = (MBeanServer) iniCtx.lookup("jmx/invoker/HttpAdaptor");
			*/

			MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
			JMSContainerInvokerMBean invoker = (JMSContainerInvokerMBean) MBeanProxy.get(
					JMSContainerInvokerMBean.class, objectName, mbeanServer);
			if (method == STOP) {
				invoker.stopDelivery();
			} else if (method == START) {
				invoker.startDelivery();
			}
		} catch (MBeanProxyCreationException e) {
		} catch (Exception e) {
		}
	}

	/**
	 * Usage.
	 *
	 * @param s
	 */
	public static void main(String s[]) {
		DeliveryControl control = new DeliveryControl();
		String mbean = "binding=message-driven-bean,jndiName=local/DemoBean@711487,plugin=invoker,service=EJB";
		try {
			control.stopMessageDelivery(new ObjectName(mbean));
		} catch (MalformedObjectNameException e) {
		} catch (NullPointerException e) {
		}
	}
}
The MBean I am looking for that corresponds to the MDB is show in line 76. You can see that the JNDI name ends with a number. JBoss assigns this number to avoid name collisions. The downside is that this number changes when JBoss is restarted. To avoid this problem you can assign a local JNDI name to your bean which doesnt not change after a restart. The following ejb-jar.xml shows how to assign a local JNDI name.

    
        Listens to 'Demo' messages
        Demo MDB to demonstrate JMS features

        DemoBean
        ejb/DemoLocal
        com.ksi.demo.ejb.DemoBean

        Container
        Type='Even'
        Auto-acknowledge
        
            javax.jms.Queue