【问题标题】:Hazelcast, HazelcastSerializationException when putting data to mapHazelcast, HazelcastSerializationException 将数据放入地图时
【发布时间】:2016-08-09 11:17:37
【问题描述】:

我的应用基于 spring boot + hazelcast。

我正在尝试将简单实体保存到 hazelcast 中:

public class ExampleMeeting implements Serializable {

  private static final long serialVersionUID = 1L;

  private String id;
  private String name;

  public ExampleMeeting(String id, String name) {
    this.id = id;
    this.name = name;
  }

  public ExampleMeeting() {
  }

// getters and setters
}

我的服务方法如下:

@CachePut(value = MEETING_CACHE_NAME, key = "#meeting.id")
  public ExampleMeeting saveMeeting(ExampleMeeting meeting) {
    LOGGER.info("Save meeting to cache {}", meeting);
    return meeting;
  }

当我尝试使用跟踪存储收到的com.hazelcast.nio.serialization.HazelcastSerializationException 的实体时:

com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable de-serializer for type 2. This exception is likely to be caused by differences in the serialization configuration between members or between clients and members.
    at com.hazelcast.internal.serialization.impl.AbstractSerializationService.newHazelcastSerializationException(AbstractSerializationService.java:173)
    at com.hazelcast.internal.serialization.impl.AbstractSerializationService.readObject(AbstractSerializationService.java:200)
    at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataInput.readObject(ByteArrayObjectDataInput.java:600)
    at com.hazelcast.cluster.impl.ConfigCheck.readData(ConfigCheck.java:215)
    at com.hazelcast.cluster.impl.JoinMessage.readData(JoinMessage.java:98)
    at com.hazelcast.cluster.impl.JoinRequest.readData(JoinRequest.java:68)
    at com.hazelcast.internal.serialization.impl.DataSerializer.read(DataSerializer.java:121)
    at com.hazelcast.internal.serialization.impl.DataSerializer.read(DataSerializer.java:47)
    at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:46)
    at com.hazelcast.internal.serialization.impl.AbstractSerializationService.readObject(AbstractSerializationService.java:204)
    at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataInput.readObject(ByteArrayObjectDataInput.java:600)
    at com.hazelcast.cluster.impl.MulticastService.receive(MulticastService.java:201)
    at com.hazelcast.cluster.impl.MulticastService.run(MulticastService.java:159)
    at java.lang.Thread.run(Thread.java:745)

这是我的 hazelcast 配置:

@Bean
  HazelcastInstance hazelcastInstance() {

    Config config = new ClasspathXmlConfig(hazelcatsConfig);

    Map<String, MapConfig> mapConfigMap = new HashMap<String, MapConfig>();

    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(applicationContext);
    for (BeanDefinition bd : scanner.findCandidateComponents("com.egalacoral.spark")) {
      String className = bd.getBeanClassName();
      try {
        Class<?> classObj = Class.forName(className);
        Method[] methods = classObj.getDeclaredMethods();
        for (Method method2 : methods) {
          Cacheable annotation = AnnotationUtils.getAnnotation(method2, Cacheable.class);
          if (annotation != null && annotation.value().length > 0) {
            addMap(mapConfigMap, method2, annotation);
          }
        }
      } catch (ClassNotFoundException e) {
        LOGGER.error("Error while creating maps for caches", e);
      }
    }
    config.setMapConfigs(mapConfigMap);
    return Hazelcast.newHazelcastInstance(config);
  }

请告诉我如何解决这个问题。

更新

 protected void addMap(Map<String, MapConfig> mapConfigMap, Method method2, Cacheable annotation) {
    MapConfig mapConfig = new MapConfig();
    HazelcastMapConfig cacheConfig = AnnotationUtils.getAnnotation(method2, HazelcastMapConfig.class);
    mapConfig.setEvictionPolicy(cacheConfig.evictionPolicy());
    String timeToLiveSeconds = cacheConfig.timeToLiveSeconds();
    if (StringUtils.hasText(timeToLiveSeconds)) {
      timeToLiveSeconds = this.embeddedValueResolver.resolvePlaceholders(timeToLiveSeconds);
    }
    mapConfig.setTimeToLiveSeconds(Integer.parseInt(timeToLiveSeconds));
    String key = annotation.value()[0];
    mapConfigMap.put(key, mapConfig);
    LOGGER.info("Created map for cache {} : {} ", key, mapConfig);
  }

【问题讨论】:

  • 您是否使用自定义序列化? .addSerializerConfig(new SerializerConfig().setImplementation(serializer).setTypeClass(ExampleMeeting.class))) 之类的东西?
  • @noscreenname 感谢您的回复。不我没有。是否总是需要为 hazelcast 添加自定义序列化程序?
  • @I.Domshchikon 否,但堆栈跟踪表明它可能是由不正确的序列化配置引起的。可以加addMap(mapConfigMap, method2, annotation)的代码吗?
  • @noscreenname。我已经更新了问题。
  • @I.Domshchikon 还有一个问题:您是否使用 hazelcast 作为休眠的二级缓存?

标签: java serialization hazelcast hazelcast-imap


【解决方案1】:

这更像是一个猜测,但我在 hazelcast github 上找到了类似的 issue

当从注释创建 hazelcast conf 时,可能会检测到第三方序列化程序(您是否使用 hazelcast 作为休眠缓存?)。如果是这种情况,您应该包含 jar,其中包含所有 hazelcast 实例(客户端和服务器)中的序列化类。

【讨论】:

    【解决方案2】:

    I.Domshchikov,

    您是否有机会在 SO 中查看有关在 Spring(引导)环境中使用 Hazelcast 的答案?

    Hazelcast Caching for Clusterd Spring Application

    谢谢

    【讨论】:

      猜你喜欢
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 2020-01-27
      • 1970-01-01
      • 2018-10-02
      相关资源
      最近更新 更多