Another transaction problem
jimdowning Aug 24, 2001 9:52 AMHi,
I'm afraid that despite all the posts and the documentation on this subject I'm still at sea with a problem with transactions in an MDB.
I have an MDB that connects to an external socket server. Since the socket server is not a jboss managed resource do the bean need to manage it's own transaction with the socket server?
When the transaction code runs, I suspect I'm not getting the right transaction - a java.rmi.RemoteException is thrown with the message "Application error: BMT stateless bean LoggingMDB should complete transactions before returning". I thought I had completed the transaction...
LoggingMDB.java
package com.paribus.hemlatta.beans.messagedriven; import java.net.Socket; import java.io.ObjectOutputStream; import javax.ejb.MessageDrivenBean; import javax.ejb.MessageDrivenContext; import javax.ejb.EJBException; import javax.jms.MessageListener; import javax.jms.Message; import javax.transaction.UserTransaction; import org.jboss.tm.TxManager; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.Category; import org.apache.log4j.Priority; public class LoggingMDB implements MessageDrivenBean, MessageListener { private MessageDrivenContext ctx = null; public LoggingMDB () { ; } public void setMessageDrivenContext(MessageDrivenContext ctx) throws EJBException { this.ctx = ctx; } public void ejbCreate() { ; } public void ejbRemove() { ; } public void onMessage(Message msg) { System.out.println("Logger got message "+ msg.toString()); try { Context ic = new InitialContext(); UserTransaction xa = (UserTransaction)ic.lookup("java:comp/UserTransaction"); String classname = "com.paribus.hemlatta.beans.messagedriven.LoggingMDB"; xa.begin(); try { LoggingEvent l = new LoggingEvent( classname, Category.getInstance(classname), Priority.INFO, msg, null); Socket socket = new Socket("localhost",2469); ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); out.writeObject(l); out.close(); socket.close(); xa.commit(); } catch (Exception e) { xa.rollback(); e.printStackTrace(); } } catch (javax.transaction.NotSupportedException e) { e.printStackTrace(); } catch (javax.transaction.SystemException e) { e.printStackTrace(); } catch (NamingException e) { e.printStackTrace(); } } }
Stack Trace
[LoggingMDB] Logger got message TextMessage@Fri Aug 24 14:32:58 GMT+01:00 2001 #1
[LoggingMDB] Application error: BMT stateless bean LoggingMDB should complete transactions before returning (ejb1.1 spec, 11.6.1)
[Container factory] Exception in JMSCI message listener: : java.rmi.RemoteException: Application error: BMT stateless bean LoggingMDB should complete transactions before returning (ejb1.1 spec, 11.6.1)
[Container factory] java.rmi.RemoteException: Application error: BMT stateless bean LoggingMDB should complete transactions before returning (ejb1.1 spec, 11.6.1)
[Container factory] at org.jboss.ejb.plugins.MessageDrivenTxInterceptorBMT.invoke(MessageDrivenTxInterceptorBMT.java:161)
[Container factory] at org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDrivenInstanceInterceptor.java:58)
[Container factory] at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:190)
[Container factory] at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:195)
[Container factory] at org.jboss.ejb.MessageDrivenContainer.invoke(MessageDrivenContainer.java:264)
[Container factory] at org.jboss.ejb.plugins.jms.JMSContainerInvoker.invoke(JMSContainerInvoker.java:151)
[Container factory] at org.jboss.ejb.plugins.jms.JMSContainerInvoker$MessageListenerImpl.onMessage(JMSContainerInvoker.java:448)
[Container factory] at org.jbossmq.SpyMessageConsumer.deliverMessage(SpyMessageConsumer.java:294)
[Container factory] at org.jbossmq.SpySession.run(SpySession.java:236)
[Container factory] at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:131)
[Container factory] at org.jboss.jms.asf.ThreadPool$Worker.run(ThreadPool.java:128)
ejb-jar.xml
<?xml version="1.0"?> <!DOCTYPE ejb-jar> <ejb-jar> <enterprise-beans> <message-driven> <ejb-name>LoggingMDB</ejb-name> <ejb-class>com.paribus.hemlatta.beans.messagedriven.LoggingMDB</ejb-class> <message-selector/> <transaction-type>Bean</transaction-type> <acknowledge-mode>Auto-acknowledge</acknowledge-mode> <message-driven-destination> <destination-type>javax.jms.Queue</destination-type> </message-driven-destination> </message-driven> </enterprise-beans> </ejb-jar>
thanks,
jim