【问题标题】:java.lang.ClassCastException: [B cannot be cast to java.util.List when using Redisjava.lang.ClassCastException: [使用 Redis 时无法将 B 强制转换为 java.util.List
【发布时间】:2020-06-04 16:19:47
【问题描述】:

我有以下代码:

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

objects 是一个字符串列表。代码大部分时间运行良好。但意外引发以下异常。

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)

如果我再次运行相同的代码,它使用相同的数据运行良好。无法理解此类问题的原因。

【问题讨论】:

  • 尝试发布更多代码?
  • 什么是'B'?你需要更具体
  • @Stultuske [Bbyte[]。这不是由 OP 定义的。看到这个:docs.oracle.com/javase/7/docs/api/java/lang/…
  • @Nitin 我知道这是一篇旧帖子;但我在使用另一个项目时遇到了类似的问题。你知道发生了什么事吗?

标签: java redis classcastexception


【解决方案1】:

TL;DR

Jedis 实例不是线程安全的,跨多个线程调用 Jedis 实例会导致这些类型的错误。尝试切换到使用JedisPool 来管理连接的创建。

说明

我看到了这些完全相同的异常,并且在试图找出问题时遇到了类似的issue on the Jedis project,解释 Jedis 不是线程安全的。

由于我在搜索相同的异常时发现了这个问题,因此我将分享我的特定案例的一些细节,以便对未来的读者有所帮助。

在我的特殊情况下,我使用来自 Spring Data Redis 的 RedisTemplate 调用 SCAN 命令。我在连接生命周期之外调用了生成的Cursor

我的原始代码如下所示。

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();
}

经过一个小改动后,我发现正确的方法是在执行 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();
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-15
    • 2017-10-14
    • 2019-10-04
    • 2016-09-05
    • 1970-01-01
    相关资源
    最近更新 更多