cancel
Showing results for 
Search instead for 
Did you mean: 

Message acknowledgment in JMS message driven bean

Former Member
0 Kudos

Hi all,

I have a problem with the acknowledgment of messages sent to a message bean. The bean listens to a queue. In the ejb-jar.xml transaction-type "Container" and a container-transaction entry with attribute "Required" for the "onMessage" method is defined. Just a plain simple example from the tutorial.

According to the JMS spec I expected that messages received by the bean are acknowledged at the end of the "onMessage" method automatically, but somehow this seems not to work on 6.40/SP11. The bean receives and processes messages sent to the queue sucessfully, but afterwards they remain in the queue as unacknowledged (checked in the corresponding database table).

Even worse, when I try to redeploy the bean the SDM hangs, likely due to the undelivered messages in the queue (after manual deletion of the messages in the db and restarting of the engine deployment works again...until the bean receives another message).

Any ideas?

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

Hi Michael,

The problem you are experiencing could be caused if you are using non-transacted JMS connection factory with the transactions in the MDB.

If that is the case and you are using the provided default factories, then please open the file jms-factories.xml from your ear and change from

<link-factory-name>

jmsfactory/default/QueueConnectionFactory

</link-factory-name>

to

<link-factory-name>

jmsfactory/default/XAQueueConnectionFactory

</link-factory-name>

Best Regards

Peter Peshev

Former Member
0 Kudos

Hi Peter,

that was indeed the problem. After fixing jms-factories.xml my bean now correctly acknowledges received messages.

Thanks for your help!

Best Regards

Michael

0 Kudos

Hi Michael,

The message acknowledgement in J2EE Engine 6.40 SP11 seems to work fine, so probably we should get some more info about your example. Please note that an acknowledge status with value 01 in the database table means 'acknowledged'. In case a message has been acknowledged, it will be deleted from the table after 10 minutes. So if you check the table contents just after the message receipt, the message will be still there (probably with acknowledge status 01). It is also possible that one part of your messages have been successfully processed by the message-driven bean while the others have not. So please check whether the messages left in the database (with status 00) have been successfully processed by the message-driven bean.

As about the hanging, you can refer to SAP Note 710154 - How to create a thread dump for the J2EE Engine 6.30. Here are the steps in brief:

on Windows:

1. Open the SAP Management Console.

2. Navigate to the Process table of the Java instance.

3. Right-click on the Java node and choose "Dump Stack Trace" from the context menu.

on all platforms you can use the JCMon tool to initiate a thread dump:

1. Start the JCMon program with the profile of the instance.

The JCMon binary is located in the /usr/sap/<SID>/<Instance>/j2ee/os_libs directory or in the /usr/sap/<SID>/SYS/exe/run directory.

2. Enter "20" to go to the "Local Administration Menue".

3. Choose the "Dump stacktrace" menu item by entering its number.

4. Select the Java node from the list of processes above and enter the value from the "Idx" column.

5. Confirm the command with a "y" if the selected node is correct.

Finally, you can find the full thread stacks in the following file:

- /usr/sap/<SID>/<Instance>/work/std_<node name>.out file (for JDK's from SUN and HP);

- /usr/sap/<SID>/<Instance>/j2ee/cluster/javacore<PID>.<timestamp>.txt file (for JDK's from IBM).

You can then find exactly where the hanging happens. It can be in the application code or somewhere in the server classes.

Hope it helps.

Best regards,

Vesselin.

Former Member
0 Kudos

Hi Vesselin,

the "onMessage" method of my bean is fairly simple:

[code]

public void onMessage(Message message) {

TextMessage msg = null;

try {

if (message instanceof TextMessage) {

msg = (TextMessage) message;

String text = msg.getText();

} else {

trace.infoT("onMessage", "invalid messsage type");

}

} catch (JMSException e) {

trace.catching("onMessage", e);

} catch (Throwable t) {

trace.catching("onMessage", t);

}}

[/code]

I attached to this method with the remote debugger and sent a message.

The processing went through fine without exceptions. However, afterwards I see a single entry in BC_JMSQUEUE with ACK=00.

I found three "suspicious" entries in std_server0.out.

The second seems to be the most relevant since it says that "onMessage" waits for some comitment.

In the order of occurence in std_server0.out:

[code]

"SAPEngine_Application_Thread[impl:3]_18" prio=5 tid=0x3c989ff0 nid=0xbe0 in Object.wait() [3d93f000..3d93fdb0]

at java.lang.Object.wait(Native Method)

- waiting on <0x1d897af8> (a java.lang.Object)

at java.lang.Object.wait(Object.java:429)

at com.sap.jms.client.session.Session.stopDeliveryToListeners(Session.java:905)

at com.sap.jms.client.session.Session.pauseDelivery(Session.java:851)

- locked <0x1d897af8> (a java.lang.Object)

at com.sap.jms.client.connection.Connection.stop(Connection.java:436)

at com.sap.engine.services.jmsconnector.cci.ConnectionImpl.stop(ConnectionImpl.java:214)

at com.sap.engine.services.jmsconnector.cci.ConnectionImpl.close(ConnectionImpl.java:231)

at com.sap.engine.services.jmsconnector.cci.QueueConnectionImpl.close(QueueConnectionImpl.java:69)

at com.sap.engine.services.ejb.message.JMSBridge.unregisterListener(JMSBridge.java:231)

at com.sap.engine.services.ejb.message.MessageContainer.destroy(MessageContainer.java:185)

at com.sap.engine.services.ejb.ApplicationThreadDestroyer.destroyContainers(ApplicationThreadDestroyer.java:58)

at com.sap.engine.services.ejb.ApplicationThreadDestroyer.run(ApplicationThreadDestroyer.java:41)

- locked <0x1124c048> (a java.lang.Object)

at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)

at java.security.AccessController.doPrivileged(Native Method)

at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:94)

at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:162)

[/code]

[code]

"SAPEngine_Application_Thread[impl:3]_7" prio=5 tid=0x3cae38e8 nid=0x754 in Object.wait() [3d67f000..3d67fdb0]

at java.lang.Object.wait(Native Method)

- waiting on <0x1d8979e8> (a java.lang.Object)

at java.lang.Object.wait(Object.java:429)

at com.sap.jms.client.session.Session.waitCommit(Session.java:1925)

- locked <0x1d8979e8> (a java.lang.Object)

at com.sap.jms.client.connection.ConnectionConsumer$ConsumerListener.onMessage(ConnectionConsumer.java:139)

at com.sap.jms.client.session.Session.run(Session.java:527)

at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)

at java.security.AccessController.doPrivileged(Native Method)

at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:94)

at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:162)

[/code]

[code]

"SAPEngine_Application_Thread[impl:3]_0" prio=5 tid=0x3cb25d20 nid=0xb48 in Object.wait() [3d4bf000..3d4bfdb0]

at java.lang.Object.wait(Native Method)

- waiting on <0x1124c048> (a java.lang.Object)

at java.lang.Object.wait(Object.java:429)

at com.sap.engine.services.ejb.EJBAdmin.destroyContainers(EJBAdmin.java:1117)

- locked <0x1124c048> (a java.lang.Object)

at com.sap.engine.services.ejb.EJBAdmin.commitStop(EJBAdmin.java:2503)

at com.sap.engine.services.deploy.server.application.StopTransaction.commonCommitFinished(StopTransaction.java:252)

at com.sap.engine.services.deploy.server.application.StopTransaction.commitCommon(StopTransaction.java:295)

at com.sap.engine.services.deploy.server.application.StopTransaction.commit(StopTransaction.java:281)

at com.sap.engine.services.deploy.server.application.ApplicationTransaction.makeAllPhasesOnOneServer(ApplicationTransaction.java:308)

at com.sap.engine.services.deploy.server.application.ParallelAdapter.makeAllPhasesImpl(ParallelAdapter.java:301)

at com.sap.engine.services.deploy.server.application.ParallelAdapter.runInTheSameThread(ParallelAdapter.java:110)

at com.sap.engine.services.deploy.server.application.ParallelAdapter.makeAllPhasesAndWait(ParallelAdapter.java:212)

at com.sap.engine.services.deploy.server.application.ApplicationTransaction.makeNestedParallelTransaction(ApplicationTransaction.java:571)

at com.sap.engine.services.deploy.server.application.UpdateTransaction.needStopApplicationPhase(UpdateTransaction.java:583)

at com.sap.engine.services.deploy.server.application.UpdateTransaction.getContainersWhichNeedUpdate(UpdateTransaction.java:540)

at com.sap.engine.services.deploy.server.application.UpdateTransaction.getConcernedContainers(UpdateTransaction.java:469)

at com.sap.engine.services.deploy.server.application.DeployUtilTransaction.commonBegin(DeployUtilTransaction.java:356)

at com.sap.engine.services.deploy.server.application.UpdateTransaction.begin(UpdateTransaction.java:148)

at com.sap.engine.services.deploy.server.application.ApplicationTransaction.makeAllPhasesOnOneServer(ApplicationTransaction.java:290)

at com.sap.engine.services.deploy.server.application.ApplicationTransaction.makeAllPhases(ApplicationTransaction.java:323)

at com.sap.engine.services.deploy.server.DeployServiceImpl.makeGlobalTransaction(DeployServiceImpl.java:3033)

at com.sap.engine.services.deploy.server.DeployServiceImpl.update(DeployServiceImpl.java:580)

at com.sap.engine.services.deploy.server.DeployServiceImplp4_Skel.dispatch(DeployServiceImplp4_Skel.java:1278)

[/code]

Best regards

Michael