Hazelcast, HazelcastSerializationException при помещении данных на карту

Мое приложение основано на 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);
  }

person I. Domshchikov    schedule 09.08.2016    source источник
comment
Вы используете настраиваемую сериализацию? Что-то вроде .addSerializerConfig(new SerializerConfig().setImplementation(serializer).setTypeClass(ExampleMeeting.class)))?   -  person noscreenname    schedule 09.08.2016
comment
@noscreenname Спасибо за ответ. Нет у меня нет. Всегда ли нужно добавлять собственный сериализатор для hazelcast?   -  person I. Domshchikov    schedule 09.08.2016
comment
@ I.Domschikon нет, но stacktrace предположил, что это могло быть вызвано некорректной конфигурацией сериализации. Можете ли вы добавить код addMap(mapConfigMap, method2, annotation)?   -  person noscreenname    schedule 09.08.2016
comment
@noscreenname. Я обновил вопрос.   -  person I. Domshchikov    schedule 09.08.2016
comment
@ I.Домщик еще один вопрос: вы используете hazelcast как спящий кеш 2-го уровня?   -  person noscreenname    schedule 10.08.2016
comment
@ I.Domschikon вам не нужно регистрировать какие-либо кастомные сериализаторы, если вы используете java Serializable (как в вашем примере). Должно работать "из коробки" с Serializable и Externalizable. Не могли бы вы разместить здесь воспроизводимый пример на GH? Спасибо   -  person Vik Gamov    schedule 12.08.2016
comment
Кстати, я написал блог о том, как вы можете использовать Spring Boot с Hazelcast next.javaheadbrain.com/posts/2015/12/31/. TL; DR, Spring boot имеет поддержку jcache и Hazelcast из коробки с   -  person Vik Gamov    schedule 12.08.2016
comment
Вы успели прочитать мой ответ? Спасибо   -  person Vik Gamov    schedule 15.08.2016
comment
@VikGamov. Извините, у меня нет возможности это искать, но я сделаю это   -  person I. Domshchikov    schedule 16.08.2016


Ответы (2)


Это скорее предположение, чем ответ, но я нашел аналогичную проблему на hazelcast github .

Возможно, что когда hazelcast conf создается из аннотаций, обнаруживаются сторонние сериализаторы (вы используете hazelcast в качестве кеш-памяти гибернации?). В этом случае вы должны включить jar-файлы, содержащие классы сериализации, во все экземпляры hazelcast (клиент и сервер).

person noscreenname    schedule 10.08.2016

И. Домщиков,

Была ли у вас возможность проверить этот ответ в SO об использовании Hazelcast в среде Spring (Boot)?

Кэширование Hazelcast для приложения Clusterd Spring

Спасибо

person Vik Gamov    schedule 12.08.2016