- Notifications
You must be signed in to change notification settings - Fork 586
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.