R.Diab OCEWSD6,OCAJP8,OCPJP8,OCEWCD6,OCEJPAD6,OCEEJBD6,
But what will happen to the message sent to JMS queue ?
It will be removed also ?
I understand from Specs that in CMT with transaction attribute required , sending the message is part of a transaction
That means my message will never sent to the queue ?
R.Diab OCEWSD6,OCAJP8,OCPJP8,OCEWCD6,OCEJPAD6,OCEEJBD6,
The container delivers the message to a CMT in the same transaction in which the onMessage() method runs. This means that if a System Exception is thrown, the message is put back on the incoming queue and the container will try once more to deliver it to the MDB .
In case of a BMT the delivery of a message to the onMessage() method of the MessageDriven bean is outside the transaction. This means that if a System Exception is thrown from the onMessage method, the transaction that you started by UserTransaction.begin() is rolled back, but the message is not put back on the incoming queue for redelivery.
BMT: a message is redelivered if the onMessage method throws a RuntimeException
CMT: a message is redelivered if the onMessage method throws a RuntimeException.
I am sure the RuntimeException on in this case refers to System Exception.
Q1: Quote A says in BMT the message won't be redelivered when the onMessage throws a system exception or runtime exception which is not application exception. Quote B says in BMT the message will be redelivered when the onMessage throws a system exception. Which quote is the right one?
5.4.18 Dealing with Exceptions
If a message-driven bean uses bean-managed transaction demarcation and throws a RuntimeException, the container should not acknowledge the message.
Q2: In JSR-318, when a system exception is thrown from the onMessage method, the MDB will be destroyed and the @PreDestroy interceptor is called. So, if MDB does not exist after the system exception is thrown, how can the EJB container put the message to the queue/topic and redeliver to the MDB? The only possibility is the EJB container put the same message to the queue/topic and redeliver the message to a new instance of MDB.
the message is put back on the incoming queue and the container will try once more to deliver it to the MDB.
when the message is not acknowledged (within a certain period) of time, the underlying messaging resource provider will attempt to redeliver the message (note that this redelivery is not specified in the EJB specs, but this is how most messaging providers have implemented it)
the underlying messaging resource provider redelivers the message to the EJB container and then the container redelivers the same message to a new instance of MDB?
Info: *** MessageProducerServlet created.
Info: *** QueueListenerEJB created. 1
Info: *** Bean 1 received message: com.sun.messaging.jms.ra.DirectObjectPacket@442cde28
Info: Received message with number: 1
Info: Message string: Hello Message Driven Beans
Info: Message time: Wed Mar 18 18:35:51 EDT 2015
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: message-driven bean method public abstract void javax.jms.MessageListener.onMessage(javax.jms.Message) system exception
..
at com.ivan.scbcd6.ejbs.QueueListenerEJB.onMessage(QueueListenerEJB.java:39)
....
Warning: MDB00037: [QueueMessageDrivenExample:QueueListener2]: Message-driven bean invocation exception: [javax.ejb.EJBException]
Warning: javax.ejb.EJBException
javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5194)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5092)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4880)
at com.sun.ejb.containers.MessageBeanContainer.afterMessageDeliveryInternal(MessageBeanContainer.java:1207)
at com.sun.ejb.containers.MessageBeanContainer.afterMessageDelivery(MessageBeanContainer.java:1180)
at com.sun.ejb.containers.MessageBeanListenerImpl.afterMessageDelivery(MessageBeanListenerImpl.java:86)
at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:143)
at com.sun.proxy.$Proxy190.afterDelivery(Unknown Source)
at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:328)
at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:114)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
Caused by: java.lang.RuntimeException
at com.ivan.scbcd6.ejbs.QueueListenerEJB.onMessage(QueueListenerEJB.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
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.invokeTargetBeanMethod(BaseContainer.java:4155)
at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5347)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5327)
at com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:1093)
at com.sun.ejb.containers.MessageBeanListenerImpl.deliverMessage(MessageBeanListenerImpl.java:81)
at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:171)
at com.sun.proxy.$Proxy190.onMessage(Unknown Source)
at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:260)
... 3 more
Info: *** QueueListenerEJB created. 2
Info: *** Bean 2 received message: com.sun.messaging.jms.ra.DirectObjectPacket@442cde28
Info: Received message with number: 1
Info: Message string: Hello Message Driven Beans
Info: Message time: Wed Mar 18 18:35:51 EDT 2015
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: message-driven bean method public abstract void javax.jms.MessageListener.onMessage(javax.jms.Message) system exception
....
Caused by: java.lang.RuntimeException
.....
Info: MQJMSRA_MR1101: run:Message returned & marked for routing to the DMQ
Warning: MDB00037: [QueueMessageDrivenExample:QueueListener2]: Message-driven bean invocation exception: [javax.ejb.EJBException]
Warning: javax.ejb.EJBException
javax.ejb.EJBException
...
Caused by: java.lang.RuntimeException
....
Info: Server shutdown initiated
Warning: [MDBContainer] Current thread done cleanup()...
Warning: [MDBContainer] Current thread done cleanup()...
Warning: [MDBContainer] Current thread done cleanup()...
Warning: [MDBContainer] Current thread done cleanup()...
Info: MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter stopping...
Info: MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter stopped.
Info: RAR7094: jmsra shutdown successful.
Info: JMXStartupService: Stopped JMXConnectorServer: null
Info: JMXStartupService and JMXConnectors have been shut down.
Info: Shutdown procedure finished
MessageProducerServlet created.
Info: *** QueueListenerEJB created. 1
Severe: MDB00050: Message-driven bean [QueueMessageDrivenExample:QueueListener2]: Exception in creating message-driven ejb : [com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@Field-Injectable Resource. Class name = com.ivan.scbcd6.ejbs.QueueListenerEJB Field [email protected]@com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@@ into class com.ivan.scbcd6.ejbs.QueueListenerEJB]
Severe: com.sun.enterprise.container.common.spi.util.InjectionException
com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@Field-Injectable Resource. Class name = com.ivan.scbcd6.ejbs.QueueListenerEJB Field [email protected]@com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@@ into class com.ivan.scbcd6.ejbs.QueueListenerEJB
...
at com.sun.ejb.containers.MessageBeanContainer.beforeMessageDelivery(MessageBeanContainer.java:989)
at com.sun.ejb.containers.MessageBeanListenerImpl.beforeMessageDelivery(MessageBeanListenerImpl.java:77)
at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:163)
at com.sun.proxy.$Proxy189.onMessage(Unknown Source)
.....
Caused by: java.lang.IllegalArgumentException: Can not set javax.ejb.SessionContext field com.ivan.scbcd6.ejbs.QueueListenerEJB.mBeanContext to com.sun.ejb.containers.MessageBeanContextImpl
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
at java.lang.reflect.Field.set(Field.java:657)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:649)
... 17 more
Severe: MDB00042: [QueueMessageDrivenExample:QueueListener2]: No invocation for message []
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: QueueMessageDrivenExample:QueueListener2: message-driven bean invocation closed by container
....
Info: *** QueueListenerEJB created. 2
Severe: MDB00050: Message-driven bean [QueueMessageDrivenExample:QueueListener2]: Exception in creating message-driven ejb : [com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@Field-Injectable Resource. Class name = com.ivan.scbcd6.ejbs.QueueListenerEJB Field [email protected]@com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@@ into class com.ivan.scbcd6.ejbs.QueueListenerEJB]
Severe: com.sun.enterprise.container.common.spi.util.InjectionException
com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@Field-Injectable Resource. Class name = com.ivan.scbcd6.ejbs.QueueListenerEJB Field [email protected]@com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@@ into class com.ivan.scbcd6.ejbs.QueueListenerEJB
...
at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:163)
at com.sun.proxy.$Proxy189.onMessage(Unknown Source)
at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:260)
...
Caused by: java.lang.IllegalArgumentException: Can not set javax.ejb.SessionContext field com.ivan.scbcd6.ejbs.QueueListenerEJB.mBeanContext to com.sun.ejb.containers.MessageBeanContextImpl
...
Severe: MDB00042: [QueueMessageDrivenExample:QueueListener2]: No invocation for message []
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
....
Info: MQJMSRA_MR1101: run:Message returned & marked for routing to the DMQ
MessageProducerServlet created.
Info: *** QueueListenerEJB created. 1
Severe: MDB00050: Message-driven bean [QueueMessageDrivenExample:QueueListener1]: Exception in creating message-driven ejb : [com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@Field-Injectable Resource. Class name = com.ivan.scbcd6.ejbs.QueueListenerEJB Field [email protected]@com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@@ into class com.ivan.scbcd6.ejbs.QueueListenerEJB]
Severe: com.sun.enterprise.container.common.spi.util.InjectionException
com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@Field-Injectable Resource. Class name = com.ivan.scbcd6.ejbs.QueueListenerEJB Field [email protected]@com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@@ into class com.ivan.scbcd6.ejbs.QueueListenerEJB
...
Caused by: java.lang.IllegalArgumentException: Can not set javax.ejb.SessionContext field com.ivan.scbcd6.ejbs.QueueListenerEJB.mBeanContext to com.sun.ejb.containers.MessageBeanContextImpl
....
Severe: MDB00042: [QueueMessageDrivenExample:QueueListener1]: No invocation for message []
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: QueueMessageDrivenExample:QueueListener1: message-driven bean invocation closed by container
at com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:1163)
at com.sun.ejb.containers.MessageBeanListenerImpl.deliverMessage(MessageBeanListenerImpl.java:81)
....
Info: *** QueueListenerEJB created. 2
Severe: MDB00050: Message-driven bean [QueueMessageDrivenExample:QueueListener1]: Exception in creating message-driven ejb : [com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@Field-Injectable Resource. Class name = com.ivan.scbcd6.ejbs.QueueListenerEJB Field [email protected]@com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@@ into class com.ivan.scbcd6.ejbs.QueueListenerEJB]
Severe: com.sun.enterprise.container.common.spi.util.InjectionException
com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Env-Prop: com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@Field-Injectable Resource. Class name = com.ivan.scbcd6.ejbs.QueueListenerEJB Field [email protected]@com.ivan.scbcd6.ejbs.QueueListenerEJB/mBeanContext@@ into class com.ivan.scbcd6.ejbs.QueueListenerEJB
....
at com.sun.proxy.$Proxy189.onMessage(Unknown Source)
at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:260)
....
Caused by: java.lang.IllegalArgumentException: Can not set javax.ejb.SessionContext field com.ivan.scbcd6.ejbs.QueueListenerEJB.mBeanContext to com.sun.ejb.containers.MessageBeanContextImpl
...
Severe: MDB00042: [QueueMessageDrivenExample:QueueListener1]: No invocation for message []
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: QueueMessageDrivenExample:QueueListener1: message-driven bean invocation closed by container
at com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:1163)
....
Info: MQJMSRA_MR1101: run:Message returned & marked for routing to the DMQ
Info: Server shutdown initiated
Warning: [MDBContainer] Current thread done cleanup()...
.....
Based on the three experiment above, it seems to me that Glassfish redelivers the message when UserTransaction.rollback() or system exception occurs during BMT
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: QueueMessageDrivenExample:QueueListener1: message-driven bean invocation closed by container
Info: *** QueueListenerEJB created. 1
Info: *** Transaction begin...
Info: *** Bean 1 received message: com.sun.messaging.jms.ra.DirectObjectPacket@cd7e6ef
Info: Received message with number: 1
Info: Message string: Hello Message Driven Beans
Info: Message time: Thu Mar 19 17:06:18 EDT 2015
Warning: MDB00037: [QueueMessageDrivenExample:QueueListener1]: Message-driven bean invocation exception: [javax.ejb.EJBException: MessageDrivenBean method returned without completing transaction]
Warning: javax.ejb.EJBException
javax.ejb.EJBException: MessageDrivenBean method returned without completing transaction
at com.sun.ejb.containers.BaseContainer.checkExceptionBeanMgTx(BaseContainer.java:4999)
...
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: message-driven bean method public abstract void javax.jms.MessageListener.onMessage(javax.jms.Message) system exception
at com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:1128)
...
Caused by: java.lang.RuntimeException
...
at com.sun.ejb.containers.MessageBeanContainer.deliverMessage(MessageBeanContainer.java:1093)
Info: *** QueueListenerEJB created. 2
Info: *** Transaction begin...
Info: *** Bean 2 received message: com.sun.messaging.jms.ra.DirectObjectPacket@cd7e6ef
Info: Received message with number: 1
Info: Message string: Hello Message Driven Beans
Info: Message time: Thu Mar 19 17:06:18 EDT 2015
Warning: MDB00037: [QueueMessageDrivenExample:QueueListener1]: Message-driven bean invocation exception: [javax.ejb.EJBException: MessageDrivenBean method returned without completing transaction]
Warning: javax.ejb.EJBException
javax.ejb.EJBException: MessageDrivenBean method returned without completing transaction
...
Warning: MQJMSRA_MR2001: run:Caught Exception from onMessage():Redelivering:
javax.ejb.EJBException: message-driven bean method public abstract void javax.jms.MessageListener.onMessage(javax.jms.Message) system exception
...
Caused by: java.lang.RuntimeException
at com.ivan.scbcd6.ejbs.QueueListenerEJB.extractMessagePayload(QueueListenerEJB.java:107)
...
Info: *** QueueListenerEJB created. 1
Info: *** Transaction begin...
Info: *** Bean 1 received message: com.sun.messaging.jms.ra.DirectObjectPacket@61fbfb1e
Info: Received message with number: 1
Info: Message string: Hello Message Driven Beans
Info: Message time: Thu Mar 19 17:43:35 EDT 2015
Info: **** Transaction status before rollback: 0
Info: **** Transaction status after rollback : 6
However, in the status code, there is a Status_ROLLEDBACK constant = 4. I am curious why the transaction status is not 4 after the transaction is rolled back ?
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime. |