JMS APIs provides the way to send, receive messages in enterprises asynchronous way. There is no need of wait for the message to get processed in server and continue the business in client. Just post, and let it get processed. These APIs are bundles under the package javax.jms and JAVA Documentation found at JMS APIs
JMS comes with flavours of messaging - Queue(point-to-point destination) and Topic(publish/subscribe model). Best sample usecase would be, Queue will be useful to communicate any one consumer has to act on request. In cluster environment, Topic helps to send broadcast message to all the nodes.
- Message types can be byte, text or object messages. JMS provides API to construct message based on the message - javax.jms.TextMessage, javax.jms.ByteMessage, javax.jms.StreamMessage and javax.jms.ObjectMessage.
- javax.jms.ConnectionFactory helps to define connection configuration properties such as Transaction, LoadBalancing and etc.,. Using ConnectionFactory, Connection get created. Using this javax.jms.Connection, javax.jms.Session is created to post/receive message.
- Queue/Topic helps to locate or point the destination where the message has to go and/or pulled from.
- javax.jms.QueueSession exposes APIs to create sender, receiver, browser and Queue.
QueueBrowser used to read message from Queue without deleting from Queue. - javax.jms.TopicSession exposes APIs to create publisher, consumer, and Topic.
Here is simple example code which helps to post/receive text message from weblogic server.
import java.util.Hashtable;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class QSendTest {
public static void main(String[] args)
throws Exception {
QueueConnectionFactory qconFactory = null;
QueueConnection qcon = null;
QueueSession qsession = null;
Queue queue = null;
TextMessage msg = null;
InitialContext ctx = getInitialContext();
qconFactory = (QueueConnectionFactory)
ctx.lookup("jms/MyQueueFactory");
qcon = qconFactory.createQueueConnection();
qsession = qcon.createQueueSession(false,
QueueSession.AUTO_ACKNOWLEDGE);
queue = (Queue) ctx.lookup("jms/MyQueue");
//Posting message to Queue
QueueSender qsender = qsession.createSender(queue);
msg = qsession.createTextMessage();
msg.setStringProperty("MSG_ID", "12345678947");
msg.setText("Hello at " + System.currentTimeMillis());
qsender.send(msg);
System.out.println("Sent");
qsender.close();
//To receive message from Queue
qcon.start();
QueueReceiver qReceiver = qsession.createReceiver(queue);
while (true) {
TextMessage txt = (TextMessage)
qReceiver.receiveNoWait();
if (txt == null)
break;
System.out.println(txt.getText()
+ "with header MSG_ID="
+ txt.getStringProperty("MSG_ID"));
}
qReceiver.close();
qsession.close();
qcon.close();
}
private static InitialContext getInitialContext()
throws NamingException {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001/");
return new InitialContext(env);
}
}
In weblogic, javax.jms_1.1.1.jar has JMS APIs and its implementaions. Before running this program, we have set up JMS configuration in Server. Steps are given below
- Create JMS Server
-
- Login weblogic console, select services from Domain structure tab.
- Select JMS Servers
- In JMS Servers tab, click New
- Type MyJMsServer and select AdminServer
- click on finish
- Create JMS Module
-
- Login weblogic console, select services from Domain structure tab.
- Select JMS Modules
- In JMS Modules tab, click New
- Type MyJMsModule and select AdminServer
- click on finish
- Create Subdeployments
-
- Login weblogic console, select services from Domain structure tab.
- Select MyJMsModule and select subdeployments li>In Summary of Resources panel, click New
- Type MyQueue and select MyJMsServer
- click on finish
- Create JMS Connection Factory
-
- Login weblogic console, select services from Domain structure tab.
- Select JMS Modules and select MyJMsModule
- In Summary of Resources panel, click New
- Select Connection Factory and say Next
- Type Name as MyQueueFactory and JNDI Name as jms/MyQueueFactory
- Click Next and Finish
- Create JMS Queue
- Login weblogic console, select services from Domain structure tab.
- Select JMS Modules and select MyJMsModule
- In Summary of Resources panel, click New
- Select Queue and say Next
- Type Name as MyQueue and JNDI Name as jms/MyQueue
- Click Next and Finish
- Create JMS Queue
- Login weblogic console, select services from Domain structure tab.
- Select JMS Modules and select MyJMsModule and MyQueue
- In Summary of Resources panel, click New
- Select Queue and say Next
- Type Name as MyQueue and JNDI Name as jms/MyQueue
- Click Next and Finish
3 comments:
It is very useful and easy to understand the JMS.
Thanks!
Satya Prasad Balla.
On of the best JMS example :)
Thanks!
Amazing.....you are.....loved this blog... simple and rocking....
The steps to configure the Queue and QCF is like a cake, mean, the way you explained....neat..
To run the code, u need weblogic.jar in the classpath as well.
Then Weblogic needs a restart.
And then Bingo............. :)
Message went to the Queue...
A caution from my experience here. During the run, i saw this
===
Exception in thread "main" javax.naming.NameNotFoundException: Unable to resolve 'jms.MyQueue'. Reso
lved 'jms' [Root exception is javax.naming.NameNotFoundException: Unable to resolve 'jms.MyQueue'. R
esolved 'jms']; remaining name 'MyQueue'
at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:234)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:348)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:259)
at weblogic.jndi.internal.ServerNamingNode_1035_WLStub.lookup(Unknown Source)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:423)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:411)
at javax.naming.InitialContext.lookup(Unknown Source)
at QSendTest.main(QSendTest.java:30)
Caused by: javax.naming.NameNotFoundException: Unable to resolve 'jms.MyQueue'. Resolved 'jms'
at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139
)
at weblogic.jndi.internal.BasicNamingNode.lookupHere(BasicNamingNode.java:252)
at weblogic.jndi.internal.ServerNamingNode.lookupHere(ServerNamingNode.java:182)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:206)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:214)
at weblogic.jndi.internal.RootNamingNode_WLSkel.invoke(Unknown Source)
at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:667)
at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:230)
at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:522)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:518)
at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
e:\ADSamples\WeblogicQueueTest>java QSendTest
===
Couple of hit on the google told me that server may need a restart as the new configuration to be effective.. but this is sometime.. Here is the link that resolve my issue.
https://kr.forums.oracle.com/forums/thread.jspa?threadID=1086442
And there the program execution went well..
thanks to you for this article...
Post a Comment