我遇到JBoss EAP 6和WebSphere MQ的问题。我开发了一个消息驱动的bean:
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/VGT.EXTERN.IN"),
@ActivationConfigProperty(propertyName = "clientID", propertyValue = "VGT_BYSENDINGSYSTEMDISPATCHERMDB") })
@Pool(value = "BySendingSystemDispatcherMDB-pool")
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class BySendingSystemDispatcherMDB implements javax.jms.MessageListener {
private Logger logger = Logger.getLogger(getClass());
@Inject
@Named
BySendingSystemDispatcher bySendingSystemDispatcher;
@Resource
MessageDrivenContext mdc;
@Inject
@Named
Listener listener;
@Override
public void onMessage(Message message) {
try {
// Weiterbearbeitung deligieren
bySendingSystemDispatcher.onMessage(message);
} catch (JMSException e) {
listener.handleExceptionWhenMessageIsPoisend(e);
logger.error(e.getLinkedException(), e);
mdc.setRollbackOnly();
} catch (JAXBException e) {
mdc.setRollbackOnly();
listener.handleExceptionWhileProcessingMessage(message, e);
logger.error(e.getMessage(), e);
} catch (ClassCastException e) {
logger.error(e.getMessage(), e);
mdc.setRollbackOnly();
} catch (Exception e) {
logger.error(e.getMessage(), e);
mdc.setRollbackOnly();
} finally {
// logging
if (logger.isDebugEnabled()) {
String id = null;
try {
id = message.getJMSMessageID();
logger.debug(((TextMessage) message).getText());
} catch (Exception e) {
logger.debug("logging of message - " + id + " failed");
}
}
}
}
bySendingSystemDispatcher.onMessage(message)方法引发从java.lang.Exception派生的异常,并用@ApplicationException(rollback = true)注释。如果发生这种情况,该消息将按照配置重新传递5次,此后它将在资源适配器中循环,并且不再传递。我已经用HornetQ检查了相同的情况,它按预期工作。
MQ将引发以下异常
Class : class javax.jms.JMSException
Stack : com.ibm.msg.client.commonservices.trace.Trace.ffst(Trace.java:1611)
: com.ibm.msg.client.wmq.common.internal.messages.WMQSendMarshal.constructMQMD(WMQSendMarshal.java:287)
: com.ibm.msg.client.wmq.common.internal.messages.WMQSendMarshal.exportMQMDAndMessageBuffers(WMQSendMarshal.java:503)
: com.ibm.msg.client.wmq.common.internal.messages.WMQSendMarshal.exportMQMD(WMQSendMarshal.java:567)
: com.ibm.msg.client.wmq.internal.WMQPoison$PoisonMessage.calculateMqmdAndBuffers(WMQPoison.java:1816)
: com.ibm.msg.client.wmq.
有趣的一点是,您可以在MQMD头中找到一个超出退出阈值的退出计数。
知道会发生什么以及如何解决吗?
约尔格
最佳答案
我们已经找到了资源循环适配器被迫循环的原因。由于不正确,我们没有正确配置boq,因此max-msg-len属性比引用队列小8倍。如果存在一条消息,则该消息大于boq的max-msg-len,并且有一个异常迫使它移至boq,ressource-adapter尝试将其放入boq并失败。通常,ressouce-adapter然后应将其移动到dlq,但这也失败了,因为事务丢失了。在移至dlq失败后,ressource-adapter并未丢弃该消息,但再次尝试将其移至boq,boq再次失败并开始了循环。
我认为ressource-adapter的行为并不是真的正确,但是如果同步max-msg-len属性,就不会出现此问题。
感谢Umapathy的支持。
约尔格