Hazelcast - java.lang.IllegalArgumentException:key不能是Data类型

时间:2018-06-12 14:11:05

标签: java hazelcast

我们刚刚将我们的应用程序从Hazelcast 3.8.0升级到3.10.1。

我们收到错误消息"密钥不能是数据类型!"在Hazelcast中访问数据时。

java.lang.IllegalArgumentException: key cannot be of type Data!
at com.hazelcast.util.Preconditions.checkNotInstanceOf(Preconditions.java:300)
at com.hazelcast.internal.nearcache.impl.DefaultNearCache.checkKeyFormat(DefaultNearCache.java:226)
at com.hazelcast.internal.nearcache.impl.DefaultNearCache.get(DefaultNearCache.java:114)
at com.hazelcast.map.impl.tx.TransactionalMapProxySupport.getCachedValue(TransactionalMapProxySupport.java:183)
at com.hazelcast.map.impl.tx.TransactionalMapProxySupport.getInternal(TransactionalMapProxySupport.java:132)
at com.hazelcast.map.impl.tx.TransactionalMapProxy.get(TransactionalMapProxy.java:110)
at com.hazelcast.client.impl.protocol.task.transactionalmap.TransactionalMapGetMessageTask.innerCall(TransactionalMapGetMessageTask.java:43)
at com.hazelcast.client.impl.protocol.task.AbstractTransactionalMessageTask.call(AbstractTransactionalMessageTask.java:34)
at com.hazelcast.client.impl.protocol.task.AbstractCallableMessageTask.processMessage(AbstractCallableMessageTask.java:35)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.initializeAndProcessMessage(AbstractMessageTask.java:130)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.run(AbstractMessageTask.java:110)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:64)
at com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:80)
at ------ submitted from ------.(Unknown Source)

我100%确定"键"我们正在使用的是一个字符串。代码段如下所示:

 String key = getKey(blah, blah);

 TransactionContext context = client.newTransactionContext();
 context.beginTransaction();
 TransactionalMap<String, AppPrefs> dataMap = context.getMap(MAP_NAME);
 try {
        prefs = dataMap.get(key);
        context.commitTransaction();

     } catch (Throwable t) {
        LOGGER.error("Error getting AppPrefs.", t);
        context.rollbackTransaction();
     }

抛出错误的代码行是:

prefs = dataMap.get(key);

设置String

的代码行之间没有任何内容
String key = getKey(blah, blah);

和吹的线:(

通过源代码,TransactionalMapProxySupport的方法&#34; toNearCacheKeyWithStrategy&#34;有这个逻辑:

final Object toNearCacheKeyWithStrategy(Object key) {
    if (!nearCacheEnabled) {
        return key;
    }

    return serializeKeys ? ss.toData(key, partitionStrategy) : key;
}

&#34; DefaultNearCache&#34;对象然后做了

private void checkKeyFormat(K key) {
    if (!serializeKeys) {
        checkNotInstanceOf(Data.class, key, "key cannot be of type Data!");
    }
}

所以它看起来像&#34; TransactionalMapProxySupport&#34;叫&#34; serializeKeyes&#34;必须是FALSE但是&#34; DefaultNearCache&#34;中的同名属性必须是真的:(

&#34; DefaultNearCache&#34;的历史在git中显示代码在一年前更改了消息:&#34;将序列化键默认为Near Cache从true变为false&#34;

我应该设置一些配置吗?

我对地图的配置很简单:

<near-cache name="AppPrefsCache">
  <!-- Cache locally for 10 mins -->
  <max-idle-seconds>600</max-idle-seconds>
</near-cache>

啊!我似乎可以添加一个&#34;序列密钥&#34;标记(true | false)到此xml并设置值。

Hazelcast代码库的不同位似乎为&#34; serialize-keys&#34;假设了不同的默认值。它应该是配置中的必需元素,或者默认值应该是相同的,是吗?是的?

1 个答案:

答案 0 :(得分:0)

上述行为实际上是Hazelcast中的错误。我为此创建了一个新的GitHub问题,因此我们可以正确处理它-hazelcast/hazelcast#13371

受此错误影响的版本的解决方法是在serialize-keys配置中将true设置为near-cachefalse的值在这里无济于事。

Config config = new Config();
config.getMapConfig(testName)
    .setNearCacheConfig(new NearCacheConfig().setSerializeKeys(true));

感谢彼得的报告和深入的调查。