Skip to content

JMS via remote OpenMQ and genericra

by Matthias Fraass on Januar 8th, 2010

Our second example in this series will cover how to connect Glassfish v3 to a remote OpenMQ server.

Glassfish V3 brings a complete OpenMQ installation under glassfish/mq. It is started in embedded mode when Glassfish is started. But you can deploy or start it externally, so you can have a basic load distribution or whatever your demands might be to do that.

So let’s take the tour on how to talk to a remote OpenMQ server.

First, we start a separate OpenMQ instance on Port 7677. We can’t use the default port (7676) as this would interfer with the embedded server. Plus, our previous example is still working this way:

mq/bin>imqbrokerd.bat -port 7677

Then start the Admin GUI via

mq/bin>imqadmin.bat

And configure OpenMQ:

  1. add a broker for port 7677 and connect to it (u/p admin/admin)
  2. add a target “GenericRAQueue”, type Queue
  3. add a ObjectStore:
  • call it “openMQObjectStore”
  • add two properties:
    - java.naming.provier.url=file:///c:/somewhere/you/like
    - java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory
  • add a target: “MyQueue” -> “GenericRAQueue”
  • add a ConnectionFactory:
    - name “MyQueueConnectionFactory”
    - type XAConnectionFactory
  • on tab “Connection Handling”, set Port to 7677

The OpenMQ is now configured.

Now Download genericra.rar from the project’s website and put it to \temp\genericra\

The next step is to configure Glassfish. I added the steps for deleting or undeploying the configuration, so ignore the errors. It’s important that the create/deploy commands are successfull, though:

rem asadmin undeploy –cascade genericra
rem asadmin delete-resource-adapter-config genericra

asadmin deploy \temp\genericra\genericra.rar

asadmin create-resource-adapter-config –property SupportsXA=true:ProviderIntegrationMode=jndi:UserName=admin:Password=admin:JndiProperties=java.naming.factory.initial\=com.sun.jndi.fscontext.RefFSContextFactory,java.naming.provider.url\=file\:///c\:/dev/glassfishv3rel1/mq/objstore,java.naming.security.principal\=admin,java.naming.security.credentials\=admin:LogLevel=FINEST genericra

rem asadmin delete-connector-connection-pool –cascade OpenMQ_GRA_CP
rem asadmin delete-connector-resource OpenMQ_GRA
rem asadmin delete-jmsdest –desttype queue Queue4GenericRA
rem asadmin delete-admin-object Queue4GenericRA

asadmin create-connector-connection-pool –raname genericra –connectiondefinition javax.jms.ConnectionFactory –transactionsupport XATransaction –property ConnectionFactoryJndiName=MyQueueConnectionFactory OpenMQ_GRA_CP
asadmin create-connector-resource –poolname OpenMQ_GRA_CP OpenMQ_GRA
asadmin create-admin-object –raname genericra –restype javax.jms.Queue –property DestinationJndiName=MyQueue Queue4GenericRA

Now you can send messages to the Queue with this RESTful Webservice. You can add it to the one we created in the first part of this series:

@Stateless
@Path(“/jms”)
public class JMSRestfulWebService {

@Resource(mappedName = “OpenMQ_GRA”)
private ConnectionFactory openMQGenericRAConnectionFactory;

@Resource(mappedName = “Queue4GenericRA”)
private Queue openMQGenericRAQueue;

@Path(“openmqgeneric”)
@GET
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public String putMessageOpenMQGeneric() throws NamingException, JMSException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException
{
System.out.println(“called putMessageOpenMQGeneric”);

javax.jms.Connection connection = openMQGenericRAConnectionFactory.createConnection();
javax.jms.Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(openMQGenericRAQueue);
TextMessage message = session.createTextMessage();
message.setText(“Hello, openMQ via genericra! #”);
messageProducer.send(message);

return “JMS remotely produced 1 messages via adapter #”;
}

}

Just open http://localhost:8080/yourcontext/jms/openmqgeneric with a web browser and you should see in the log file that a message was created. You can check the Queue in the OpenMQ Admin GUI for the number of messages in the Queue – it should increase.

So let’s consume these messages with a MessageDrivenBean!

Add this to a sun-ejb-jar.xml (create it, if it’s not there yet):

<enterprise-beans>
	<ejb>
		<ejb-name>MyOpenMQGenericRAMessageDrivenBean</ejb-name>
		<mdb-resource-adapter>
			<resource-adapter-mid>genericra</resource-adapter-mid>
		</mdb-resource-adapter>
	</ejb>
</enterprise-beans>

And this is the MDB which receives the messages:

package de.osp.test.jms;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(mappedName = “Queue4GenericRA”
,activationConfig = {
@ActivationConfigProperty(propertyName = “ConnectionFactoryJndiName”, propertyValue = “MyQueueConnectionFactory”)
,@ActivationConfigProperty(propertyName = “DestinationJndiName”, propertyValue=”MyQueue”)
}
)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class MyOpenMQGenericRAMessageDrivenBean implements MessageListener {

/**
* Default constructor.
*/
public MyOpenMQGenericRAMessageDrivenBean() {
// TODO Auto-generated constructor stub
}

/**
* @see MessageListener#onMessage(Message)
*/
public void onMessage(Message message) {
try {
System.out.println(“### MyOpenMQGenericRAMessageDrivenBean got message: ” + ((TextMessage)message).getText() + ” @” + System.currentTimeMillis());
} catch (JMSException e) {
e.printStackTrace();
}

}

}

It should receive the queued messages as soon as you deploy it.

Be adviced that this combination is a bit unstable in Glassfish, so if you get error messages, simply try to restart Glassfis, then redeploy the application and then restart Glassfish again.

I hope this helps as it took me some time to figure it out!

Stay tuned for more articles in this series. But I won’t promise when I’ll have time again to write again ;) .

From → Coding

2 Comments
  1. Eivind permalink

    I’ve run into a challenge when running the command

    asadmin create-resource-adapter-config

    I want to use an LDAP-based JNDI, and I’m unable to find a way to specify the parameters java.naming.provider.url and java.naming.security.credentials:

    The problem is that the parameters are set in the comma-separated list “JndiProperties=…,…,…”, and the values I wan to set contain commas themselves (e.g. java.naming.provider.url=ldap://host:389/ou=objects,dc=example.com).

    I can’t find a way to encode/escape those commas so that the asadmin command will be accepted. I keep getting
    com.sun.enterprise.admin.cli.CommandException: remote failure: Invalid property syntax

    Any hints on this?

  2. You have to escape the commas (separate the JndiProperties), the equals signs (separate property keys and property values) and the colons (separate properties).

    E.g.
    java.naming.provider.url=ldap://host\:389/ou\=objects\,dc\=example.com

    Also if you’re under Linux, you have to escape the backslashes :/.

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS