JMS Plugin
This plugin allows you to expose your Service artifacts as Message-Driven POJOs/POGOs using Spring's JMS support, described http://www.springframework.org/docs/reference/jms.html. This enables your Services to receive messages from a JMS broker without implementing any special interfaces. As of version 0.2, the plugin also enables the easy sending of JMS messages from Grails Controllers and Services.
Note The plugin only works with Grails 0.6 and above.
Setup
1.2 Creating a Connection Factory
The use of the JMS Plugin requires that you have a bean named connectionFactory defined in grails-app/conf/spring/resources.xml. See your broker's documentation for instructions for how to do this. For example, using ActiveMQ's default configuration:
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean>
Usage
2.1 Exposing your Service
To expose your service as an MDP, you need to create a message listener closure or method. By default, this needs to be called onMessage, although you can override this as we'll see below. Once you've defined your message listener, simply add a static property called expose and set it to a list containing 'jms'. For example:
class SampleQueueService {
static expose = ['jms']
def onMessage = {
println "GOT MESSAGE: $it"
}
}
If you define onMessage as a method, that'll work too:
class SampleQueueService {
static expose = ['jms']
def onMessage(messageObject) {
println "GOT MESSAGE: $messageObject"
}
}
By default, this will attach this service as a message listener to a JMS Queue named sampleQueue
| XFire/Remoting Compatibility You may notice that the configuration is similar to that for the XFire and Remoting plugin. |
2.2 Additional Configuration
There are a number of configuration changes you can make by setting various static properties on your service class:
| static listenerCount = 5 | Spawns 5 threads to listen for messages | defaults to 1 |
| static destination = "OtherQueueName" | Sets an alternate destination name | defaults to Service's property name |
| static listenerMethod = "handleMessage" | Sets an alternate listener method (or closure) name |
defaults to "onMessage" |
| static pubSub = true | Tells the Spring JMS classes to use Topic instead of Queue | defaults to false |
| static messageSelector = "MessageType = 'DATA'" | Associates JMS Message Selector to the listener | defaults to null |
| static durable = true | Creates a durable subscription (applies to Topics only) | defaults to false |
| static clientId = "myclient" | Provides a client identifier for durable subscriptions. | defaults to "grailsAppListener", id property can be used instead of clientId for backwards compatibility |
3 Sending JMS Messages
As of version 0.2 of the plugin, Service and Controller artefacts have these closures defined:
- sendQueueJMSMessage & sendJMSMessage - send messages to a Queue destination
- sendJMSMessage & sendPubSubJMSMessage - send messages to a Topic destination
All closures take two parameters: the destination name and the message. For example, here's a save action closure that sends a JMS message upon entity creation:def save = { def blogEntry = new BlogEntry(params) if(!blogEntry.hasErrors() && blogEntry.save()) { flash.message = "BlogEntry ${blogEntry.id} created" sendJMSMessage("sample", "Blog Entry entitled ${blogEntry.title} has been created.") redirect(action:show,id:blogEntry.id) } else { render(view:'create',model:[blogEntry:blogEntry]) } }
Configuration Examples
Here are some specific sample configurations.
Active MQ
- Download ActiveMQ from http://activemq.apache.org/
- Add activemq-core-4.1.1.jar, backport-util-concurrent-3.0.jar, geronimo-j2ee-management_1.0_spec-1.0.jar, and geronimo-jms_1.1_spec-1.0.jar from the ActiveMQ distribution into the lib directory of your Grails application.
- Add this to your conf/spring/resources.xml changing the brokerURL based on your ActiveMQ configuration:
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> </bean>
- Start ActiveMQ
JBossMQ (running inside JBossAS)
This applies to Grails applications deployed inside JBossAS.
- Download JBossAS from http://labs.jboss.com/jbossas/
- Add this to your conf/spring/resources.xml:
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:/ConnectionFactory"/> </bean>
JBossMQ (running outside JBossAS)
This applies to Grails application deployed outside JBossAS or in a separate JBossAS instance from the one running JBossMQ.
- Download JBossAS from http://labs.jboss.com/jbossas/
- Add jbossall-client.jar (from JBOSS_HOME/client) to the lib directory of your Grails application
- Add this to your conf/spring/resources.xml:
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="ConnectionFactory" /> <property name="jndiEnvironment"> <props> <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop> <prop key="java.naming.provider.url">localhost:1099</prop> </props> </property> </bean>

