Hi All,
Here is a Example of MDB 3.0 which gets deployed on WebLogic Server 10 and above and starts consuming messages from javax.jms.Queue . This Example demonstrates us, How we can develop MDB3.0 for Oracle WebLogic Application Server.
For More details on MDB3.0 Standard Annotations which makes our MDB Application container specific API independent please refer to the following link: MDB With Non-Container-Specific-Annotations
Step 1). first of all we need to develop the MDB class like below
package ejb30; import javax.ejb.MessageDriven; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; import javax.ejb.ActivationConfigProperty; @MessageDriven( activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") , @ActivationConfigProperty(propertyName="connectionFactoryJndiName",propertyValue="QCF"), @ActivationConfigProperty(propertyName="destinationJndiName", propertyValue="TestQ") } ,mappedName="TestQ" ) public class MyMDB implements MessageListener { public void onMessage(Message message) { TextMessage textMessage = (TextMessage) message; try { System.out.println("nnt(mdb) MyMDB Received n"+ textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } }
Step 2). Compile the Above MDB class and then create a JAR out of it.
javac –d . MyMDB.java
jar -cvf mdb30.jar ejb30 MyMDB.java
Step 3). Now Logic to WebLogic Admin console and create a ConnectionFactory with JNDI Name “QCF” and a Queue with JNDI Name “TestQ”.
Step 4). Deploy the MDB Jar (mdb30) file on the Server.
Step 5). Now start Writing the Client Queue Sender Program which is going to send some JMS messages to the TestQ and as a listener the MDB is going to consume these JMS messages.
import java.io.IOException; import java.util.Hashtable; import javax.jms.JMSException; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; public class QueueSend { // Defines the JNDI context factory. public final static String JNDI_FACTORY="weblogic.jndi.WLInitialContextFactory"; // Defines the JMS context factory. public final static String JMS_FACTORY="QCF"; // Defines the queue. public final static String QUEUE="TestQ"; private QueueConnectionFactory qconFactory; private QueueConnection qcon; private QueueSession qsession; private QueueSender qsender; private Queue queue; private TextMessage msg; public void init(Context ctx, String queueName) throws NamingException, JMSException { qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY); qcon = qconFactory.createQueueConnection(); qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); queue = (Queue) ctx.lookup(queueName); qsender = qsession.createSender(queue); msg = qsession.createTextMessage(); qcon.start(); } public void send(String message,int counter) throws JMSException { msg.setText(message); msg.setIntProperty("counter", counter); qsender.send(msg); } public void close() throws JMSException { qsender.close(); qsession.close(); qcon.close(); } public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("Usage: java QueueSend WebLogicURL"); return; } InitialContext ic = getInitialContext(args[0]); QueueSend qs = new QueueSend(); qs.init(ic, QUEUE); readAndSend(qs); qs.close(); } private static void readAndSend(QueueSend qs) throws IOException, JMSException { String line="Test Message Body with counter = "; for(int i=0;i<10;i++){ qs.send(line+i,i); System.out.println("JMS Message Sent: "+line+i+"n"); } } private static InitialContext getInitialContext(String url) throws NamingException { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY); env.put(Context.PROVIDER_URL, url); return new InitialContext(env); } }
Step 6). Compile the above program and then run it.
javac –d . QueueSend.java
java QueueSend t3://localhost:7001
Step 7). Now in Admin Console Go to the Monitoring Tab of the JMS Queue and see how many messages are getting consumed by MDB and how many messages are pending in the queue.
regards
Jay SenSharma
August 18th, 2009 on 1:20 am
Good to see ur blog 🙂
Keep writing…would like to read updates on Weblogic
March 23rd, 2010 on 4:26 pm
Some more updates you will find here now….
Thanks for visiting
April 10th, 2010 on 8:20 am
Hi sensharma, this sample is very useful..
I’m facing the issue when compile QueueSend class linux environment,
but windows it works great.
in windows I compile the class like this :
C:beauser_projectsdomainsMyDomainbin>setDomainEnv.cmd
C:beauser_projectsdomainsMyDomain>java QueueSend t3://localhost:7001
JMS Message Sent: Test Message Body with counter = 0
JMS Message Sent: Test Message Body with counter = 1
…..
in Linux :
after ./setDomainEnv,
$bea…MYDOMAINbin >java QueueSend t3://localhost:7001
Exception in thread “main” java.lang.NoClassDefFoundError: javax/jms/Message
Caused by: java.lang.ClassNotFoundException: javax.jms.Message
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
I think it cannot find the java_home or classpath properly, how to solve this issue?
thanks
April 10th, 2010 on 9:05 am
Hi Muhkah,
I have updated the Forum as well: http://forums.oracle.com/forums/thread.jspa?messageID=4222507�
Please add the “modulesjavax.jms_1.1.1.jar” file also in the Client ClassPath.
Recommended & Best Option
But the Best thing i will suggest it to Just add the “wlfullClient.jar” file in the client ClassPath…this is a very useful Jar file which solves many many issues. There is a very simple way to create this JAR file: *http://jaysensharma.wordpress.com/2010/02/03/building-wlfullclient-jar/*
The advantage of using “wlfullclient.jar” is Just Make it once and then reuse this single Jar in any client Application which is going to interact with WebLogic. This Powerful Jar contains almost all the Classes which is needed by a Client.
.
.
Thanks
Jay SenSharma
June 23rd, 2010 on 2:55 pm
Hi Joy,
I have tried all the steps. and i am getting below JNDI naming exception.
————————————-
Exception in thread “main” javax.naming.NameNotFoundException: Unable to resolve ‘TestQ’. Resolved ” [Root exception is javax.naming.NameNotFoundException: Unable to resolve ‘TestQ’. Resolved ”]; remaining name ‘TestQ’
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)
—————————
I have followed the same steps mentiond to create connection factory, queue.
Please advise.
June 23rd, 2010 on 4:01 pm
Hi Rocks,
I think that your JMS module configuration may not be correct. Are u able to see the “TestQ” in the JNDI tree of the Targeted Server?
If not then Please “un target” and “re target” the Queue (TestQ).
U can also refer to Step1) Step2) and Step3) mentioned in the following Link: http://middlewaremagic.com/weblogic/2010/01/27/jaxrpc-service-with-wljmstransport/
.
.
Keep Posting 🙂
Thanks
Jay SenSharma
June 23rd, 2010 on 10:07 pm
Thanks a lot Jay…
It worked like always after consulting you.
I have 2 questions .
1. what is subdeployment and the need for that. can we have the sub deply with Connection factory
2. can we target Connection factory to JMS server. It gives option if i try to add sub deployement otheriwse shows target options for only admin/managed servers.
Please advise.
thanks.
July 20th, 2010 on 5:39 pm
thanks for such a beautiful blog
Please tell me about t3://localhost:7001 and getInitialContext function.
July 20th, 2010 on 5:49 pm
Hi Vijay,
Every Application Server provides the Implementation of JNDI (Java Naming and Directory Interface API)… Which allows us to Bind and Lookup remote Objects binded in the JNDI registry. We can lookup in the JNDI tree of a Server using the javax.naming.InitialContext Object.
In weblogic the Implementation classname for InitialContextFactory is “weblogic.jndi.WLInitialContextFactory”
We need to tell to the JVM that where the Server is running with it’s JNDI implementation … so we need to provide the “Context.PROVIDER_URL” as well…in the Above sample my Server was running on “localhost:7001” so i used the Same address inside the “getInitialContext(String Url)” method.
“t3” is a Protocol. Which is more efficient while communication with WLS. This protocol is specially designed to improve the performance between Java-to-Java communications.
.
.
Keep Posting 🙂
Thanks
Jay SenSharma
July 21st, 2010 on 7:40 pm
Is there any new in MDB ejb3.0 architecture.can i send some acknoledge message from MyMDB to QueueSend class?
July 21st, 2010 on 9:00 pm
Hi Kunlam,
So far i m not aware of any new feature which was added regarding “send some acknoledge message from MyMDB to QueueSend program back”…But i will try to find it out and will update u soon if i will get to know about similar functionality. But yes WebLogic 10.3.2 Onwards Oracle started providing support for some new annotations as mentioned in the following link: http://middlewaremagic.com/weblogic/2010/06/09/mdb-with-non-container-specific-annotations/.
Some annotations mentioned in the above link were already available from WLS10 onwards. But there are some annotations mentioned in that link which are added from WLS11g onwards.
.
.
Keep Posting 🙂
Thanks
Jay SenSharma