eclipse-ee4j / openmq

OpenMQ
https://projects.eclipse.org/projects/ee4j.openmq/
Other
52 stars 34 forks source link

Using the same session in two consecutive JTA transactions causes exception #145

Open glassfishrobot opened 12 years ago

glassfishrobot commented 12 years ago

I have a session bean which uses bean-managed transactions as follows: (The full bean is pasted below)

userTransaction.begin();
// create connection, session and message producer
// sends a message
userTransaction.commit();

userTransaction.begin();
// sends a message using the same message producer
// closes the connection
userTransaction.commit();

This works fine in GlassFish 3.1.2 with a LOCAL broker. However if the broker is embedded, the second call to send() throws a JMSException. The exception is:

javax.jms.JMSException: MQJMSRA_DS4001: JMSServiceException on send message:sendMessage: Sending message failed. Connection ID: 7219891807378463744
    at com.sun.messaging.jms.ra.DirectSession._sendMessage(DirectSession.java:1844)
    at com.sun.messaging.jms.ra.DirectProducer._send(DirectProducer.java:1085)
    at com.sun.messaging.jms.ra.DirectProducer.send(DirectProducer.java:453)
    at beans.BugExample.performTest(BugExample.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
    at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
    at $Proxy277.performTest(Unknown Source)
    at beans.__EJB31_Generated__BugExample__Intf____Bean__.performTest(Unknown Source)
    at servlets.Servlet1.handle(Servlet1.java:148)
    at servlets.Servlet1.processRequest(Servlet1.java:62)
    at servlets.Servlet1.doGet(Servlet1.java:83)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722)
Caused by: com.sun.messaging.jmq.jmsservice.JMSServiceException: sendMessage: Sending message failed. Connection ID: 7219891807378463744
    at com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.sendMessage(IMQDirectService.java:1956)
    at com.sun.messaging.jms.ra.DirectSession._sendMessage(DirectSession.java:1839)
    ... 64 more
Caused by: com.sun.messaging.jmq.jmsserver.util.BrokerException: transaction failed: 
Unexpected Broker Exception: [received message with Unknown Transaction ID 7219891807396659712: ignoring message]
    at com.sun.messaging.jmq.jmsserver.data.handlers.DataHandler.routeMessage(DataHandler.java:467)
    at com.sun.messaging.jmq.jmsserver.data.protocol.ProtocolImpl.processMessage(ProtocolImpl.java:953)
    at com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.sendMessage(IMQDirectService.java:1949)
    ... 65 more

The full bean is:

package beans;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.jms.*;
import javax.transaction.UserTransaction;

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
@LocalBean
public class BugExample {

    @Resource(lookup = "jms/connectionFactory")
    ConnectionFactory connectionFactory;

    @Resource(lookup="jms/inboundQueue")
    Queue inboundQueue;

    @Resource UserTransaction ut;

    public void performTest() throws Exception {

        System.out.println("BugExample.performTest");

        ut.begin();

        Connection connection = connectionFactory.createConnection();
        Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
        MessageProducer messageProducer = session.createProducer(inboundQueue);
        TextMessage textMessage = session.createTextMessage("Hello world");
        messageProducer.send(textMessage);

        ut.commit();

        ut.begin();

        TextMessage textMessage2 = session.createTextMessage("Hello world");

        System.out.println("BugExample.performTest: A");
        try {
            messageProducer.send(textMessage2);
        } catch (JMSException ex) {
            Logger.getLogger(BugExample.class.getName()).log(Level.SEVERE, "Error in send", ex);
        }

        System.out.println("BugExample.performTest: B");

        connection.close();

        ut.commit();

    }
}

Affected Versions

[4.5.2]

glassfishrobot commented 6 years ago
glassfishrobot commented 12 years ago

@glassfishrobot Commented Reported by @nigeldeakin

glassfishrobot commented 12 years ago

@glassfishrobot Commented @nigeldeakin said: A brief investigation suggests that when the message is sent in the second transaction, the packet that is sent contains the transactionID from the first transaction. Since this transaction was committed this causes the broker to return an "unknown transaction" error.

The cause seems to be that when a message is sent, the transactionid is copied from the DirectSession to the Packet being sent. However this transactionid is not re-initialised when the second transaction is started.

glassfishrobot commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA MQ-145