-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Redis PING command throws ClassCastException when client is in SUBSCRIBE mode #4162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi, Thanks for the detailed report. I tried to reproduce the Tested with Note: I have verified the array output for PING is returned when subscribed & using RESP2
Also took a look at the code, and it seems array output is kind of expected and already handled (supportingLink) Could you provide an example code on how to reproduce it? Hope it helps! |
Hey @ggivo Thanks for the super Fast Response. In the Code snippet attached above you are trying to just call the ping() function instead if you try to call the ping function on the jedis instance you create above you will be able to reproduce it. Adding the Updated Code snippet which is still giving me java.lang.ClassCastException Here is the updated Code snippet with the only change being ping() replaced with jedis.ping() in the onMessage Callback import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.RedisProtocol;
class Scratch {
public static void main(String[] args) {
try {
Jedis jedis = new Jedis("localhost", 6379, DefaultJedisClientConfig.builder().protocol(
RedisProtocol.RESP2).build());
jedis.subscribe(new JedisPubSub() {
@Override
public void onMessage(String channel, String message) {
if (message.equals("SEND_PING")) {
jedis.ping();
}
System.out.println("Received message: " + message);
}
@Override
public void onPong(String pattern) {
System.out.println("Received PONG: " + pattern);
}
}, "mychannel");
}
catch (Exception e) {
e.printStackTrace();
}
}
} Complete Stack Trace of the Exception java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class [B (java.util.ArrayList and [B are in module java.base of loader 'bootstrap')
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:268)
at redis.clients.jedis.Jedis.ping(Jedis.java:339)
at Scratch$1.onMessage(Main.java:17)
at Scratch$1.onMessage(Main.java:13)
at redis.clients.jedis.JedisPubSubBase.process(JedisPubSubBase.java:139)
at redis.clients.jedis.JedisPubSubBase.proceed(JedisPubSubBase.java:92)
at redis.clients.jedis.Jedis.subscribe(Jedis.java:7941)
at Scratch.main(Main.java:13) |
Thanks, I see. From
Testing locally seems this applies to @sumitswami78 |
Yeah, with RESP3 there seems to be no issue. No particular reason to not use One generic Doubt here, if Thanks @ggivo |
PING is a regular command used to test the connection, and if it makes it to the Redis server and you get a PONG, it means the connection is up and running. |
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:
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():
The getStatusCodeReply() method is implemented as follows, following implementation can be found in Connection.java file:
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:
Jedis version: 5.0.2
Redis version: 7.2.7
The text was updated successfully, but these errors were encountered: