tag:blogger.com,1999:blog-6643071316318130698.post1757224086783693571..comments2023-06-24T02:38:55.310-07:00Comments on Frank Kieviet's Engineering Notebook: JMS request/reply from an EJBfkieviethttp://www.blogger.com/profile/07479805042474878714noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-6643071316318130698.post-27315972784140373032012-03-13T21:08:42.023-07:002012-03-13T21:08:42.023-07:00I have received several similar emails like this o...I have received several similar emails like this one.<br><br>links londonhttp://www.londonoflinks.co.uk/noreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-47010419796548882012-03-13T21:08:42.022-07:002012-03-13T21:08:42.022-07:00Hi Frank,It seems a very good article.But, I did n...Hi Frank,<br><br>It seems a very good article.<br><br>But, I did not get the much things from that. It's because of my lack of understanding.<br><br>I did not get the following sentenses....Can you explain me those. It will be really great.<br><br>1) Applications can communicate with this server using a client runtime....<br><br>What this means? what is a client runtime?<br><br>2) What is meaning of the resouce adapter?<br><br>Again, please explain me...<br><br>Thanks,<br><br>Rahul<br><br>Rahulnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-61644154216608180252012-03-13T21:08:42.021-07:002012-03-13T21:08:42.021-07:00Hi, I got the same problem with a servlet where I ...Hi, I got the same problem with a servlet where I connect to a topic via JMS.<br><br>Do you acciddentally know how to resolve the transaction-issue within a servlet ?<br><br>Thnak you. Regards AgeBee<br><br>AgeBeenullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-83933012379859447212012-03-13T21:08:42.020-07:002012-03-13T21:08:42.020-07:00Hi Frank,That was a great article and very informa...Hi Frank,<br><br>That was a great article and very informative.I am trying to run a request/reply code in Glassfish.<br><br>One client is a Servlet which sends a message to the MDB (other client) and also waits for the response using receive(timeout) . I am using temporaryQueue to implement it. <br><br>But is doesnot work . The servlet gets null message or sometimes it timesout.<br><br>Also Glassfish is highly unreliable. Sometimes is throws error that Queue could not be injected (I am using Annotations ) . <br><br>Can you send me some working example of Request/Reply ? I am not using any transaction in MDB . I am very new to JMS so kindly ignore if I have done wrong somewhere.<br><br>LSKnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-69392276349290129202012-03-13T21:08:42.019-07:002012-03-13T21:08:42.019-07:00Hi Frank,Could you please send the code snippet fo...Hi Frank,<br><br>Could you please send the code snippet for using BMT SLSB from CMT MDB.<br><br>Thanks & Regards,<br><br>Pankaj<br><br>pankajnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-8122584504734017622012-03-13T21:08:42.018-07:002012-03-13T21:08:42.018-07:00Hi Frank,Are you still able to provide the code sn...Hi Frank,<br><br>Are you still able to provide the code snippet? The thread mentioned above seems to have died out without anyone providing a proper solution.<br><br>Best wishes,<br><br>Dan <br><br>Dan Duboisnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-75052319673929029532012-03-13T21:08:42.017-07:002012-03-13T21:08:42.017-07:00Hi Frank,Again, thank you very much for your respo...Hi Frank,<br><br>Again, thank you very much for your response. I would be very grateful for a code snippet. I have created a thread <a href="http://forum.java.sun.com/message.jspa?messageID=10338789" rel="nofollow">http://forum.java.sun.com/message.jspa?messageID=10338789</a> with the same topic as this but it also includes my code in question (nicely formatted). Would you be able to post the snippet there for continuity?<br><br>Best wishes,<br><br>Dan<br><br>Dan Duboisnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-84298370681940845742012-03-13T21:08:42.016-07:002012-03-13T21:08:42.016-07:00Re Dan:You're right, having the MDB delegate t...Re Dan:<br><br>You're right, having the MDB delegate to a BMT SLSB is also an option, and perhaps even a better option although it doesn't make that much difference.<br><br>I'm suspect that the error that you're getting is because you're passing the connection that you obtained in the MDB to the SLSB? This is something you need to avoid: you need to acquire a brand new connection in the SLSB. <br><br>The reason for this is that the MDB's connection is enlisted in the MDB's transaction. When you acquire a new connection in the SLSB, this new connection is enlisted in the SLSB's transaction.<br><br>It's really not much code (perhaps a dozen statements), but you have to be very careful that all the statements are in the right order and point to the right objects.<br><br>Let me know if, after checking that you're using a separate connection for sending, you still have a problem. I can send you a code snippet that illustrates the solution.<br><br>Frank<br><br>Frank Kieviethttp://blogs.sun.com/fkievietnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-64721215249812347802012-03-13T21:08:42.015-07:002012-03-13T21:08:42.015-07:00Hi Frank,Thanks for the quick reply. I realize thi...Hi Frank,<br><br>Thanks for the quick reply. I realize this is not a help forum so please feel free not to reply. :-) I thought your first solution, using a SLSB with REQUIRES_NEW to be the most elegant. Unfortunately I get the following error after my onMessage method has run through:<br><br>prepareTransaction (XA) on JMSService:jmsdirect failed for connectionId:1497195242996848640 due to TxID is already in use.<br><br>JTS5031: Exception [java.lang.RuntimeException: javax.transaction.xa.XAException] on Resource [prepare] operation.<br><br>I then decided to just delegate everything from onMessage to a BMT EJB and follow your blog's example, but still the same exception.<br><br>There seems to be very little on the net in the way of support for these types of problems. Your blog entry seems to be the only decent thing on the subject right now and it is from 2006!<br><br>Best wishes,<br><br>Dan<br><br>Dan Duboisnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-10821287493156807772012-03-13T21:08:42.014-07:002012-03-13T21:08:42.014-07:00Re Dan:Changing the transaction attribute of the M...Re Dan:<br><br>Changing the transaction attribute of the MDB has other ramifications, and you typically don't want to do that just to be able to do a request/reply.<br><br>There are two options: you can create a SLSB with the TransactionAttribute set to REQUIRES_NEW; in this SLSB you would send your request. <br><br>The other option is to use a different connection pool for sending the request. This pool would be setup in GlassFish with transaction-support = NoTransaction. This works fine with the JMSJCA resource adapter; I have not checked this with the resource adapters that come with GlassFish.<br><br>You can find JMSJCA at <a href="http://jmsjca.dev.java.net." rel="nofollow">http://jmsjca.dev.java.net.</a> <br><br>Frank<br><br>Frank Kieviethttp://blogs.sun.com/fkievietnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-88267034112551161372012-03-13T21:08:42.013-07:002012-03-13T21:08:42.013-07:00Hi Frank,I know this is an old post but I am hopin...Hi Frank,<br><br>I know this is an old post but I am hoping that you will be able to help me.<br><br>I am using Glassfish V2U2 and want to use a request/reply scenario from my MessageDrivenBean (MDB).<br><br>From what your blog says I need to change the MDB from using Container Managed Transactions to Bean Managed Transactions. Is this correct? I would be very grateful if you could tell me how I can do this.<br><br>Best wishes,<br><br>Dan<br><br>Dan Duboisnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-84835319270486626262012-03-13T21:08:42.012-07:002012-03-13T21:08:42.012-07:00> c.createQueueSession(false, Session.AUTO_ACKN...> c.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);<br><br>In fact, these arguments are ignored, so they have no effect whatsoever.<br><br>in Jboss it actually works and the message is sent before EJB transaction ended.<br><br>Also using java:/Jms to get Connection factory instead of java:/JmsXA might help:<br><br>@Resource(mappedName = "java:/Jms")<br><br>ConnectionFactory factory;<br><br>Nice blog by the way.<br><br>Vlad Enullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-42233012041087782312012-03-13T21:08:42.011-07:002012-03-13T21:08:42.011-07:00HelloFirst, thanks for the explanation, I had lots...Hello<br>First, thanks for the explanation, I had lots of trouble with this issue.<br>I found an other way to do it (although it requires application server specific code): using the TransactionManager to suspend the transaction before creating the session and resuming right after it:<br>QueueConnection c = ...;<br>TransactionManager tm = ... (AS-specific);<br>Transaction t = tm.suspend();<br>QueueSession s = c.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);<br>tm.resume(t);<br>...<br>Martinnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-27979711875456259542012-03-13T21:08:42.010-07:002012-03-13T21:08:42.010-07:00Hi Sid,If an exception happens in the main transac...Hi Sid,<br><br><br>If an exception happens in the main transaction, that transaction will be rolled back. If that results in a retry depends on what called the code: if it was called in an MDB, the JMS server will generally retry to send the message. In that case the request will be sent again.<br><br><br><br><br>What happened to the first reply? Although the main transaction was rolled back, the request was sent to the request queue (committed), and a reply was likely sent to the reply queue. Probably you would use a <i>temporary</i> queue for the reply queue. The temporary queue gets deleted automatically when the connection is closed, so effectively the reply is being discarded without being processed.<br><br><br>Frank&nbsp;<br><br><br>Frank Kievietnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-88641652519626262062012-03-13T21:08:42.009-07:002012-03-13T21:08:42.009-07:00Hi....that was a nice article and like you said......Hi....that was a nice article and like you said...something which looks to be trivial turns out to be a lot more complicated.I have one question pertaining to the request reply mode mentioned above.Like mentioned, when we send a message, we invoke it as a new transaction during which the main transaction is suspended. What would happen, if on return to the main transaction (after the message has been sent to the queue) an exception occurs in the main transaction? Will the message be reposted or this has to be taken care of programatically?? Since sending of the message is done in a seperate transaction, probably the message is not reposted if an exception occurs in the main transaction?<br>Sidnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-16987427388651816222012-03-13T21:08:42.008-07:002012-03-13T21:08:42.008-07:00Hi Aditya,You also need to call <font face=&quo...Hi Aditya,<br><br><br>You also need to call <font face="courier new,courier,monospace">Connection.start()</font> in a CMT bean.<br><br><br>When you move this code to CMT, you will have to do receive() of the message in a separate bean instance, calling a method that was declared with transaction=<font face="courier new,courier,monospace">REQUIRES_NEW</font>. This is more complicated than using BMT, so if you have the choice between CMT and BMT, I would choose BMT. You don't always have the choice: e.g. if your code resides in an MDB, you would not want to change the semantics of the onMessage() method just because you want to do a request/reply from it.<br><br><br><br><br>Frank<br><br><br><br>&nbsp;<br><br><br>Frank Kievietnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-79421308286362947822012-03-13T21:08:42.007-07:002012-03-13T21:08:42.007-07:00Hi Frank,That was quick!!Thanks for your response ...Hi Frank,<br>That was quick!!Thanks for your response and you were spot on!! I had not called connection.start() when I am using the UserTransaction!Now, I am getting a response message!!But do you think I must call the same when I am using container managed transaction?<br>Any other pitfalls that i must look out for in case of CMP? Because my team out here is quite apprehensive of using user transactions in a bean and would definitely like to port the application to a CMP bean.<br>Again, Thanks a million for your help!!<br>Adityanullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-7813770203596437702012-03-13T21:08:42.006-07:002012-03-13T21:08:42.006-07:00Hi Aditya,The first thing I always check when I ge...Hi Aditya,<br><br>The first thing I always check when I get null messages if I called <tt>connection.start()</tt>: I've made that mistake so often it's not funny anymore.<br><br>Did you call <tt>connection.start()</tt>? <br><br>Frank<br>Frank Kievietnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-67704572958749360952012-03-13T21:08:42.005-07:002012-03-13T21:08:42.005-07:00Hi Frank,Your blog really showed some intresting c...Hi Frank,<br>Your blog really showed some intresting concepts regarding transaction control in EJBs and JMS. But however, when I try to code in such a fashion, the response message always shows up a null!!! I tried both the CMP and the BMP approach. The only difference in my code is that I am not using a temporary queue but I am using a server administered queue. I double checked whether the message is sent on the commit(it does) and the MDB associated with the first queue even processes the message. After the processing of the message, the MDB itself populates a response queue. My ejb is actually waiting for this response queue and it always times out. I have attached the code. I would appreciate your help on this.Thanks-Aditya<br>public void sendRecieve()<br>{<br>try<br>{<br>String connectionInputFactoryName = "java:comp/env/jms/costingHighLevelInputQueueCF";<br>String inputQueueName = "Java:comp/env/jms/costingHighLevelInputQueue";<br>String outputQueueName = "java:comp/env/jms/costingHighLevelOutputQueue";<br>Queue inputQueue = null;<br>Queue outputQueue = null;<br>QueueSender queueSender = null;<br>InitialContext initialContext = new InitialContext();<br>mySessionCtx.getUserTransaction().begin();<br>queueConnectionFactory = (QueueConnectionFactory) PortableRemoteObject.narrow(initialContext.lookup(connectionInputFactoryName), QueueConnectionFactory.class);<br>queueConnection = queueConnectionFactory.createQueueConnection();<br>queueSession = queueConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);<br>inputQueue = (Queue) PortableRemoteObject.narrow(initialContext.lookup(inputQueueName), Queue.class);<br>ReviewDTO reviewDTO = new ReviewDTO();<br>reviewDTO.setAgentName("Aditya Narayan Barimar");<br>queueSender = queueSession.createSender(inputQueue);<br>Message theMessage = queueSession.createObjectMessage(reviewDTO);<br>String correlationId = Long.toString(System.currentTimeMillis());<br>theMessage.setJMSCorrelationID(correlationId);<br>queueSender.send(theMessage);<br>mySessionCtx.getUserTransaction().commit();<br>mySessionCtx.getUserTransaction().begin();<br>outputQueue = (Queue) PortableRemoteObject.narrow(initialContext.lookup(outputQueueName), Queue.class); QueueReceiver queueReceiver = queueSession.createReceiver(outputQueue);<br>Message reply = queueReceiver.receive(5000);<br>System.out.println("reply message is: " + reply);<br>mySessionCtx.getUserTransaction().commit();<br>}<br>catch (Throwable t)<br>{<br>t.printStackTrace();<br>}<br>finally<br>{<br>if (queueConnection != null)<br>{<br>try<br>{<br>queueSession.close();<br>queueConnection.close();<br>System.out.println("Queue connection has been closed");<br>}<br>catch (Throwable t)<br>{<br>t.printStackTrace();<br>}<br>}<br>}<br>}<br>Adityanullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-7380934561849967472012-03-13T21:08:42.003-07:002012-03-13T21:08:42.003-07:00HiNice article. In most aplications we have requir...Hi<br>Nice article. In most aplications we have requirement of sending acknowledge/acceptance and confrmation/rejection messages back to sender application.<br>So is using request/reply i/e synchronous message communication a nice option when volume of messages to be handled is really high.<br>Also what if there is some error in receiver process/ infrastructure issue etc. What would be exception handing approach in this case.<br>thx<br>mansih<br>manish dhallhttp://blogs.sun.com/fkieviet/entry/request_reply_from_an_ejbnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-7948638486627525432012-03-13T21:08:42.002-07:002012-03-13T21:08:42.002-07:00Very Good!Very Good!<br>Luo Shifeihttp://www.open-v.comnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-6583115392095763612012-03-13T21:08:42.001-07:002012-03-13T21:08:42.001-07:00Thank you for your kind feedback! Let me know what...Thank you for your kind feedback! Let me know what topics you would be interested in.<br>Frank Kievietnullnoreply@blogger.comtag:blogger.com,1999:blog-6643071316318130698.post-91430716574720491592012-03-13T21:08:42.000-07:002012-03-13T21:08:42.000-07:00Frank,Your blog is a wonderful source of informati...Frank,<br>Your blog is a wonderful source of information on JCA, JMS and up to a certain extent JTA. Please continue posting great articles like these ones as it's hard to find good sources of information on those subjects.<br>I can't wait to read more on this !<br>Ludovic Orbanhttp://www.bitronix.benoreply@blogger.com