Today, I've setup some debug code in a fresh SVN head revision, trying
to know why the messages are not being delivered to a bridged broker
when it's restarted. I think that the problem is that the consumer used
in org.apache.activemq.network.jms.QueueBridge is no longer valid after
restarting the remote broker. When I shutdown the remote broker and
start it again, I'm getting this exception for every message I send:
[ERROR][2006/09/26.17:25:46.689][ActiveMQ Session Task]failed to forward
message on attempt: 1 reason: javax.jms.IllegalStateException: [C4064]:
Cannot perform operation, producer is closed. message:
ActiveMQBytesMessage {commandId = 5, responseRequired = true, messageId
= ID:trabucco-32843-1159284345021-1:0:1:1:1, originalDestination = null,
originalTransactionId = null, producerId =
ID:trabucco-32843-1159284345021-1:0:1:1, destination = queue://SUNRECV,
transactionId = null, expiration = 0, timestamp = 1159284346661, arrival
= 0, correlationId = null, replyTo = null, persistent = true, type =
null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId
= null, compressed = false, userID = null, content =
[EMAIL PROTECTED], marshalledProperties =
null, dataStructure = null, redeliveryCounter = 0, size = 523,
properties = null, readOnlyProperties = true, readOnlyBody = true}
ActiveMQBytesMessage{ bytesOut = null, dataOut = null, dataIn = null
}([C4064]: Cannot perform operation, producer is closed.)
[ERROR][2006/09/26.17:25:46.690][ActiveMQ Session Task]Stack:
javax.jms.IllegalStateException: [C4064]: Cannot perform operation,
producer is closed.
at
com.sun.messaging.jmq.jmsclient.MessageProducerImpl.checkState(MessageProducerImpl.java:131)
at
com.sun.messaging.jmq.jmsclient.MessageProducerImpl.send(MessageProducerImpl.java:594)
at
com.sun.messaging.jmq.jmsclient.QueueSenderImpl.send(QueueSenderImpl.java:120)
at
org.apache.activemq.network.jms.QueueBridge.sendMessage(QueueBridge.java:87)
at
org.apache.activemq.network.jms.DestinationBridge.onMessage(DestinationBridge.java:138)
at
org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:830)
at
org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:96)
at
org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:155)
at
org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:111)
at
org.apache.activemq.thread.PooledTaskRunner.access$100(PooledTaskRunner.java:26)
at
org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:44)
at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
So, I think that the problem is that the producer is not valid anymore,
and a posible solution could be try to send the message and, on error,
recreate the producer in org.apache.activemq.network.jms.QueueBridge.
But I'm suspecting that perhaps that producer is not completely opaque,
because the method:
protected MessageProducer createProducer()
is returning the created MessageProducer. But I don't know where is it used.
So, could I replace the QueueBridge producer field without fear, or
should this be made in another way?
Also, I've found that sometimes, when some message is persisted in the
bridged Queue, and I restart ActiveMQ broker (with the remote broker up)
messages are not delivered to the remote broker, showing this exception:
[ERROR][2006/09/26.16:59:25.095][ActiveMQ Session Task]failed to forward
message
on attempt: 1 reason: java.lang.NullPointerException message:
ActiveMQBytesMess
age {commandId = 5, responseRequired = true, messageId =
ID:trabucco-65508-11592
81837792-1:0:1:1:1, originalDestination = null, originalTransactionId =
null, pr
oducerId = ID:trabucco-65508-1159281837792-1:0:1:1, destination =
queue://SUNREC
V, transactionId = null, expiration = 0, timestamp = 1159281839360,
arrival = 0,
correlationId = null, replyTo = null, persistent = true, type = null,
priority
= 4, groupID = null, groupSequence = 0, targetConsumerId = null,
compressed = fa
lse, userID = null, content =
[EMAIL PROTECTED], mar
shalledProperties = null, dataStructure = null, redeliveryCounter = 0,
size = 52
3, properties = null, readOnlyProperties = true, readOnlyBody = true}
ActiveMQBy
tesMessage{ bytesOut = null, dataOut = null, dataIn = null }(null)
[ERROR][2006/09/26.16:59:25.096][ActiveMQ Session Task]Stack:
java.lang.NullPointerException
at
org.apache.activemq.network.jms.QueueBridge.sendMessage(QueueBridge.j
ava:87)
at
org.apache.activemq.network.jms.DestinationBridge.onMessage(Destinati
onBridge.java:138)
at
org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageC
onsumer.java:830)
at
org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionE
xecutor.java:96)
at
org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionEx
ecutor.java:155)
at
org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.
java:111)
at
org.apache.activemq.thread.PooledTaskRunner.access$100(PooledTaskRunn
er.java:26)
at
org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.ja
va:44)
at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Wor
ker.runTask(ThreadPoolExecutor.java:650)
at
edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Wor
ker.run(ThreadPoolExecutor.java:675)
at java.lang.Thread.run(Thread.java:595)
I've put a new log in QueueBridge.sendMessage and found that, sometimes,
the producer is null:
[INFO][2006/09/26.16:59:25.091][ActiveMQ Session
Task]QueueBridge.sendMessage, u
sing producer {null}, producerQueue {Sun Java System MQ Destination
getName(): SUNRECV
Class: com.sun.messaging.BasicQueue
getVERSION(): 3.0
isReadonly(): false
getProperties(): {imqDestinationName=SUNRECV,
imqDestinationDescription=A
Description for the Destination Object}}
I've also thought that a fast fix could be to check if the producer is
null before trying to send, but I have again the same doubt, is this
MessageProducer being registered somewere out of this code?
And anyway, I'm not sure that just dropping the MessageProducer and
recreating it should be enought for the underlying sunmq code to
reconnect. I suspect that perhaps the producerConnection needs to be
recreated. Does it sound reasonable?
Regards.