Up to this point we have looked at the standard JMS client/server architecture. The JMS specification defines an advanced set of interfaces that allow for concurrent processing of a destination's messages, and collectively this functionality is referred to as application server facilities (ASF). Two of the interfaces that support concurrent message processing, javax.jms.ServerSessionPool and javax.jms.ServerSession, must be provided by the application server in which the processing will occur. Thus, the set of components that make up the JBossMQ ASF involves both JBossMQ components and JBoss server components. The JBoss server MDB container utilizes the JMS service's ASF to concurrently process messages sent to MDBs. The responsibilities of the ASF domains are well defined by the JMS specification, so we won't go into a discussion of how the ASF components are implemented. Rather, we'll discuss how ASF components used by the JBoss MDB layer are integrated, using MBeans that allow either the application server interfaces or the JMS provider interfaces to be replaced with alternate implementations. Let's start with the org.jboss.jms.jndi.JMSProviderLoader MBean. This MBean is responsible for loading an instance of the org.jboss.jms.jndi.JMSProviderAdaptor interface into the JBoss server and binding it into JNDI. The JMSProviderAdaptor interface is an abstraction that defines how to get the root JNDI context for the JMS provider, and an interface for getting and setting the JNDI names for the Context.PROVIDER_URL for the root InitialContext, and the QueueConnectionFactory and TopicConnectionFactory locations in the root context. This is all that is really necessary to bootstrap use of a JMS provider. By abstracting this information into an interface, you can use alternate JMS ASF provider implementations with the JBoss MDB container. org.jboss.jms.jndi.JBossMQProvider is the default implementation of the JMSProviderAdaptor interface, and it provides the adaptor for the JBossMQ JMS provider. To replace the JBossMQ provider with an alternate JMS ASF implementation, you simply create an implementation of the JMSProviderAdaptor interface and configure the JMSProviderLoader with the classname of the implementation. You'll see an example of this later in this chapter. In addition to being able to replace the JMS provider used for MDBs, you can also replace the javax.jms.ServerSessionPool interface implementation. This is possible by configuring the classname of the org.jboss.jms.asf.ServerSessionPoolFactory implementation, using the org.jboss.jms.asf.ServerSessionPoolLoader MBean PoolFactoryClass attribute. The default ServerSessionPoolFactory factory implementation is the JBoss org.jboss.jms.asf.StdServerSessionPoolFactory class. The org.jboss.jms.jndi.JMSProviderLoader MBeanThe JMSProviderLoader MBean service creates a JMS provider adaptor and binds it into JNDI. A JMS provider adaptor is a class that implements the org.jboss.jms.jndi.JMSProviderAdaptor interface. It is used by the MDB container to access a JMS service provider in a provider-independent manner. The configurable attributes of the JMSProviderLoader service are as follows:
Listing 6.13 shows a JMSProviderLoader for accessing a remote JBossMQ server. Listing 6.13. A JMSProviderLoader for Accessing a Remote JBossMQ Server<mbean code="org.jboss.jms.jndi.JMSProviderLoader" name="jboss.mq:service=JMSProviderLoader,name=RemoteJBossMQProvider"> <attribute name="ProviderName">RemoteJMSProvider</attribute> <attribute name="ProviderUrl">jnp://remotehost:1099</attribute> <attribute name="ProviderAdapterClass"> org.jboss.jms.jndi.JBossMQProvider </attribute> <attribute name="QueueFactoryRef">XAConnectionFactory</attribute> <attribute name="TopicFactoryRef">XAConnectionFactory</attribute> </mbean> The RemoteJMSProvider can be referenced on the MDB invoker config, as shown in the jboss.xml fragment in Listing 6.14. Listing 6.14. A jboss.xml Fragment for Specifying the MDB JMSProviderAdapter<proxy-factory-config> <JMSProviderAdaptorJNDI>RemoteJMSProvider</JMSProviderAdaptorJNDI> <ServerSessionPoolFactoryJNDI>StdJMSPool</ServerSessionPoolFactoryJNDI> <MaximumSize>15</MaximumSize> <MaxMessages>1</MaxMessages> <MDBConfig> <ReconnectIntervalSec>10</ReconnectIntervalSec> <DLQConfig> <DestinationQueue>queue/DLQ</DestinationQueue> <MaxTimesRedelivered>10</MaxTimesRedelivered> <TimeToLive>0</TimeToLive> </DLQConfig> </MDBConfig> </proxy-factory-config> Incidentally, being able to specify multiple invoker-proxy-binding elements allows an MDB to listen to the same queue/topic on multiple servers because you can configure multiple bindings with different JMSProviderAdaptorJNDI settings. Alternatively, you can integrate the JMS provider by using a JCA configuration like the one shown in Listing 6.15. Listing 6.15. A jms-ds.xml Descriptor for Integrating a JMSProviderAdapter via JCA<tx-connection-factory> <jndi-name>RemoteJmsXA</jndi-name> <xa-transaction/> <adapter-display-name>JMS Adapter</adapter-display-name> <config-property name="JMSProviderAdaptorJNDI" type="java.lang.String">RemoteJMSProvider</config-property> <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic</config-property> <security-domain-and-application>JmsXARealm</security-domain-and-application> </tx-connection-factory> The org.jboss.jms.asf.ServerSessionPoolLoader MBeanThe ServerSessionPoolLoader MBean manages a factory for javax.jms.ServerSessionPool objects used by the MDB container. The configurable attributes of the ServerSessionPoolLoader service are as follows:
Integrating Non-JBoss JMS ProvidersAs mentioned previously in this chapter, you can replace the JBossMQ JMS implementation with a foreign implementation. You can take a variety of approaches to doing the replacement:
|