1

I have the following code :

jedis.mget(objects.toArray(new String[objects.size()]));

where objects is a list of string. The code runs fine most of the time. But unexpectedly raises following exception.

java.lang.ClassCastException: [B cannot be cast to java.util.List
at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:221)
at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:214)
at redis.clients.jedis.Jedis.mget(Jedis.java:383)

If i run the same code again it runs fine with same data. Can't understand the reason for such issue.

4
  • Try to post more code? Commented Jan 18, 2016 at 11:27
  • what is 'B' ? You'll need to be more specific Commented Jan 18, 2016 at 11:28
  • 2
    @Stultuske [B is a byte[]. This isn't defined by OP. See this: docs.oracle.com/javase/7/docs/api/java/lang/… Commented Jan 18, 2016 at 11:29
  • @Nitin I know this is an old post; but I am getting a similar issue using another project. Do you know what is going on? Commented Jul 11, 2018 at 18:27

1 Answer 1

-1

TL;DR

Jedis instances are not thread-safe, calls made to a Jedis instance across multiple threads will result in these types of errors. Try switching to use a JedisPool to manage the creation of connections.

Explanation

I was seeing these exact same exceptions and while trying to figure out the problem I came across a similar issue on the Jedis project explaining Jedis is not thread-safe.

Since I found this question when searching for this same exception I will share some details of my particular case so it may help future readers.

In my particular case I calling the SCAN command using RedisTemplate from Spring Data Redis. I was making calls to the resulting Cursor outside of the connections lifecycle.

My original code looked like this.

public Long size() {
    Cursor<byte[]> scan =  redisTemplate.execute((RedisConnection connection) -> connection.scan(ScanOptions.scanOptions().match(prefix + "*").build()));
    AtomicLong count = new AtomicLong();
    scan.forEachRemaining(bytes -> count.getAndIncrement());
    return count.get();
}

After a minor change I found the correct way to do this is by simply moving the cursor interactions inside the execute lambda.

public Long size() {
    return redisTemplate.execute((RedisConnection connection) -> {
        Cursor<byte[]> scan = connection.scan(ScanOptions.scanOptions().match(prefix + "*").build());
        AtomicLong count = new AtomicLong();
        scan.forEachRemaining(bytes -> count.getAndIncrement());
        return count.get();
    });
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.