weird ClassCast Exception

309 views
Skip to first unread message

Raghava Mutharaju

unread,
Apr 17, 2011, 4:42:26 PM4/17/11
to jedis...@googlegroups.com
Hi,

Here is the stack trace:

Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.List

at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:190)

at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:172)

at redis.clients.jedis.Jedis.smembers(Jedis.java:1185)

at knoelab.classification.ELClassifier.process(ELClassifier.java:212)

at knoelab.classification.ELClassifier.process(ELClassifier.java:162)

at knoelab.classification.ELClassifier.classify(ELClassifier.java:78)

at knoelab.classification.ELClassifier.main(ELClassifier.java:112)


The line in my code which generates this a call to smembers() method. It is as follows

Set<String> result = jedis.smembers(key)


On redis-cli, when I do a smembers for that key, I would get an empty list. 


If I replace jedis with shardedJedis (only 1 node) as follows -- shardedJedis.smembers(key), that exception does not arise. 


What could be the issue here?


Regards,

Raghava.


Jonathan Leibiusky

unread,
Apr 17, 2011, 5:18:28 PM4/17/11
to jedis...@googlegroups.com
Can you please send a small test to reproduce this error?
It is easier this way as I can test it exactly and help you to fix it very fast.

Thanks!

Jonathan

Raghava Mutharaju

unread,
Apr 17, 2011, 9:41:16 PM4/17/11
to jedis...@googlegroups.com
That is the problem -- it doesn't fail on the same key, but it seems to fail on similar keys. But right after the exception when I do a smembers() on the same key, it works.

Some of the keys I use are compound keys of the form -- X@Y. The common pattern in all the failed keys is that first part is the same (i.e. X). The failed keys could be X@Z, X@M etc. I don't know how to pinpoint the exact cause of error (so cannot reproduce is consistently on the same key).

Regards,
Raghava.

Jonathan Leibiusky

unread,
Apr 17, 2011, 10:15:42 PM4/17/11
to jedis...@googlegroups.com
Is it possible that you are sharing the same Jedis instance across multiple threads?

Raghava Mutharaju

unread,
Apr 17, 2011, 10:35:45 PM4/17/11
to jedis...@googlegroups.com
No, but there are 2 instances of Jedis that access the same redis server. I have an instance of Jedis as well as ShardedJedis and since there is only 1 node, there would be two connections to the same redis server. Would this be a problem?

Regards,
Raghava.

Jonathan Leibiusky

unread,
Apr 17, 2011, 10:59:09 PM4/17/11
to jedis...@googlegroups.com
No, it wouldn't be a problem.
An error like this could happen if you are using the same redis connection (Jedis, ShardedJedis, etc.) from different threads, as this could explain how is it possible that sending an smembers commands, you are trying to read back a Long (it should try to read a list of strings)
I can't think right now of a different explanation to this, of how is it possible to send an smembers and read a Long.

Raghava Mutharaju

unread,
Apr 17, 2011, 11:39:43 PM4/17/11
to jedis...@googlegroups.com
In case of multiple threads, how is it possible to read a long instead of a list of strings?

Totally unrelated question -- if I use byte[] instead of Strings in Jedis, is it a lot quicker?

Regards,
Raghava.

Jonathan Leibiusky

unread,
Apr 18, 2011, 12:37:40 AM4/18/11
to jedis...@googlegroups.com
On Mon, Apr 18, 2011 at 12:39 AM, Raghava Mutharaju <m.vijay...@gmail.com> wrote:
In case of multiple threads, how is it possible to read a long instead of a list of strings?


I will give an example, but before that you should know that every command in Jedis is basically 2 steps. First one is to send the command to Redis and the second one is to read the result in a specific way. So for example Jedis.set(String key, String value) will basically:
1. send command: SET key value
2. read bulk reply

Now lets imagine we have a single instance of Jedis called j shared between threads A and B.

Thread A:
j.smembers()

Thread B:
j.incr()

Depending on many conditions, this could run in the following sequence:
Thread A: send command SMEMBERS
Thread B: send command INCR
Thread B: read Long
BOOOOM! Response is a List of Strings but jedis is trying to parse it as Long

The only way to ensure correct sequence of sending commands and reading the right response is to NOT share Jedis instances between threads.
If needed, the way to go is to use JedisPool, which give each thread a different Jedis instance.

So that's why I guess there might be threads involved here. Please double check for that if you can.
 
Totally unrelated question -- if I use byte[] instead of Strings in Jedis, is it a lot quicker?

Yes it should. Never ran a benchmark before, will do it tomorrow as I never thought about it. But I am pretty sure it will be faster, not sure how much though.
 

Raghava Mutharaju

unread,
Apr 18, 2011, 12:46:33 AM4/18/11
to jedis...@googlegroups.com
Thank you for the explanation, that was a good example :).

I would try using byte[] and check out the performance difference.

Regards,
Raghava. 
Reply all
Reply to author
Forward
0 new messages