Description
Using version 3.0.1:
In com.rabbitmq.client.RpcClient, around line 197, there's this function:
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body)
throws IOException {
synchronized (_continuationMap) {
String replyId = properties.getCorrelationId();
BlockingCell<Object> blocker = _continuationMap.get(replyId);
_continuationMap.remove(replyId);
blocker.set(body);
}
}
The issue is, 'blocker' might be null - if we get a reply to an old request that we no longer know about. The result is blocker.set(body) throws a NullPointerException and the message is then marked for retry and goes back in the queue and it creates an infinite loop.
We fixed this by replacing:
blocker.set(body);
with:
if (blocker != null) {
blocker.set(body);
} else {
logger.warn("blocking cell was null, ignoring response for it");
}
To reproduce - just resend any old jsonrpc reply message that was created by an earlier client and you'll see it NPE.
In our testing, we ran into this when we had a call that was issued once every 15 seconds or so, and took a few seconds to complete. If we restarted the client while the server was still processing a message, we'd end up with that stray reply stuck in the queue - and the new client endlessing NPEing in a loop.