-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Description
Problem Description
According to the official Redis documentation, the PING command is allowed while the client is in SUBSCRIBE mode, and it should return a PONG response. This applies to both RESP2 and RESP3 protocols.
supporting Link
However, when using the Jedis library, calling ping() on a client that is currently in SUBSCRIBE mode results in a ClassCastException:
java.lang.ClassCastException: java.util.ArrayList cannot be cast to byte[]
Root Cause:
The issue appears to be in the implementation of the ping() method which can be found in the File Jedis.java , which internally calls getStatusCodeReply():
@Override
public String ping() {
checkIsInMultiOrPipeline();
connection.sendCommand(Command.PING);
return connection.getStatusCodeReply();
}
The getStatusCodeReply() method is implemented as follows, following implementation can be found in Connection.java file:
public String getStatusCodeReply() {
flush();
final byte[] resp = (byte[]) readProtocolWithCheckingBroken();
if (null == resp) {
return null;
} else {
return encode(resp);
}
}
The readProtocolWithCheckingBroken() method is expected to return an Object as per the given implementation which can be found in Connection.java File. It returns an ArrayList when the client is in SUBSCRIBE mode, causing the cast to byte[] to fail with a ClassCastException. Proof for the Same which shows when in SUBSCRIBE Mode in redis-cli, the PING command returns an ArrayList consisting of an empty String and the message PONG
Expected Behaviour:
The ping() method should return "PONG" when the client is in SUBSCRIBE mode, just like the Redis CLI or any compliant Redis client implementation.
Steps to Reproduce:
- Connect to Redis using Jedis.
- Call subscribe() to enter subscription mode.
- While subscribed, call ping().
- Observe the exception.
Jedis version: 5.0.2
Redis version: 7.2.7