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