Hazelcast 3.8-EA WARNING:Received 数据格式无效问题

Hazelcast 3.8-EA WARNING:Received data format is invalid issue

使用 MapLoader Hazelcast 集群(多播发现)从外部数据源加载地图时出现错误

    WARNING: [<IP>]:5702 [<cluster_name>] [3.8-EA] Received data format is invalid. (An old version of Hazelcast may be running here.)
com.hazelcast.nio.serialization.HazelcastSerializationException: Problem while reading DataSerializable, namespace: 0, id: 0, class: 'com.hazelcast.cluster.impl.JoinRequest', exception: com.hazelcast.cluster.impl.JoinRequest
    at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.rethrowReadException(DataSerializableSerializer.java:178)
    ...
Caused by: java.lang.ClassNotFoundException: com.hazelcast.cluster.impl.JoinRequest
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)

我已经在 hazelast 3.5.4 版本上对此进行了测试。它工作正常。 我们可以忽略这个警告,但不确定它的影响是什么。它还会淹没日志。

Hazelcast 的新旧版本在多播发现方面不兼容,因为内部协议已更改。也就是说,新的 Hazelcast 版本无法识别旧版本的发现数据包。

请根据以下文档更改多播组:http://docs.hazelcast.org/docs/3.8-EA/manual/html-single/index.html#multicast-element

对于那些可能 运行 在 OSGi 环境中遇到此问题的人,您可能会被 com.hazelcast.util.ServiceLoader.findHighestReachableClassLoader() 方法的细微差别所困扰,有时会选错 class Hazelcast 初始化期间的加载程序(因为它不会总是选择您在配置中设置的 class 加载程序)。下面显示了一种通过利用 Java 的上下文 class 加载程序来解决该问题的方法:

private HazelcastInstance createHazelcastInstance() {  

    // Use the following if you're only using the Hazelcast data serializers   
    final ClassLoader classLoader = Hazelcast.class.getClassLoader();

    // Use the following if you have custom data serializers that you need
    // final ClassLoader classLoader = this.getClass().getClassLoader();

    final com.hazelcast.config.Config config = new com.hazelcast.config.Config();
    config.setClassLoader(classLoader);
    final ClassLoader previousContextClassLoader = Thread.currentThread().getContextClassLoader();
    try {
        Thread.currentThread().setContextClassLoader(classLoader);
        return Hazelcast.newHazelcastInstance(config);
    } finally {
        if(previousContextClassLoader != null) {
            Thread.currentThread().setContextClassLoader(previousContextClassLoader);
        }
    }
}