Hazelcast with global serializer (Kryo) - There is no suitable de-serializer for type

拈花ヽ惹草 提交于 2021-01-28 06:12:10

问题


I’m using Hazelcast 3.9 to cluster user sessions.

To serialize the session objects, I created a global serializer implemented with Kryo (or more precisely KryoReflectionFactorySupport that allow to serialize objects without default constructor).

public class GlobalKryoSerializer implements StreamSerializer<Object> {
    //use ThreadLocal because Kryo is not thread safe
    private static final InheritableThreadLocal <Kryo> kryoThreadLocal = new InheritableThreadLocal <Kryo>() {
        @Override
        protected Kryo initialValue() {
           Kryo kryo = new KryoReflectionFactorySupport();
           //Kryo uses its own class loader       
           kryo.setClassLoader(java.lang.Thread.currentThread().getContextClassLoader());
           return kryo;
        }
    };

    public GlobalKryoSerializer(){    }

    public int getTypeId() {
        return 123;
    }

    public void destroy() {    }

    public void write(ObjectDataOutput objectDataOutput, Object object) throws IOException {
        Output output = new Output((OutputStream) objectDataOutput);
        Kryo kryo = kryoThreadLocal.get();
        kryo.writeClassAndObject(output, object);
        output.flush();
    }

    public Object read(ObjectDataInput objectDataInput) throws IOException {
        InputStream in = (InputStream) objectDataInput;
        Input input = new Input(in);
        Kryo kryo = kryoThreadLocal.get();
        Object retVal = kryo.readClassAndObject(input);
        return retVal;
    }
}

Hazelcast.xml is similar to https://github.com/hazelcast/hazelcast/blob/master/hazelcast/src/main/resources/hazelcast-default.xml with global serializer configuration:

<serialization>
      <portable-version>0</portable-version>
      <serializers>
           <global-serializer override-java-serialization="true"> GlobalKryoSerializer</global-serializer>       
      </serializers>
</serialization>

When the session is invalidated, Hazelcast fails to de-serialize with the error below (the “type number” varies from time to time):

com.hazelcast.nio.serialization.HazelcastSerializationException: There is no suitable de-serializer for type 16843028. This exception is likely to be caused by differences in the serialization configuration betw
een members or between clients and members.
        at com.hazelcast.internal.serialization.impl.AbstractSerializationService.newHazelcastSerializationException(AbstractSerializationService.java:236) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.internal.serialization.impl.AbstractSerializationService.readObject(AbstractSerializationService.java:263) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.internal.serialization.impl.ByteArrayObjectDataInput.readObject(ByteArrayObjectDataInput.java:570) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.session.HazelcastSession.deserializeMap(HazelcastSession.java:141) ~[hazelcast-tomcat7-sessionmanager-1.1.2.jar:na]
        at com.hazelcast.session.HazelcastSession.readData(HazelcastSession.java:127) ~[hazelcast-tomcat7-sessionmanager-1.1.2.jar:na]
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.readInternal(DataSerializableSerializer.java:158) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:105) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.internal.serialization.impl.DataSerializableSerializer.read(DataSerializableSerializer.java:50) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:185) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.map.impl.proxy.MapProxySupport.toObject(MapProxySupport.java:1149) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.map.impl.proxy.MapProxyImpl.remove(MapProxyImpl.java:212) ~[hazelcast-all-3.9.jar:3.9]
        at com.hazelcast.session.HazelcastSessionManager.remove(HazelcastSessionManager.java:328) ~[hazelcast-tomcat7-sessionmanager-1.1.2.jar:na]
        at com.hazelcast.session.HazelcastSessionManager.remove(HazelcastSessionManager.java:294) ~[hazelcast-tomcat7-sessionmanager-1.1.2.jar:na]
        at org.apache.catalina.session.StandardSession.expire(StandardSession.java:833) ~[catalina.jar:7.0.82]
        at org.apache.catalina.session.StandardSession.expire(StandardSession.java:732) ~[catalina.jar:7.0.82]
        at org.apache.catalina.session.StandardSession.invalidate(StandardSession.java:1264) ~[catalina.jar:7.0.82]
        at org.apache.catalina.session.StandardSessionFacade.invalidate(StandardSessionFacade.java:183) ~[catalina.jar:7.0.82]
        at org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler.logout(SecurityContextLogoutHandler.java:65) ~[spring-security-web-4.0.2.RELEASE.jar:4.0.2.RELEASE]

回答1:


Hazelcast's Tomcat Based Web Session Replication only supports Serializable objects as Session objects when you need to cluster them. This requirement also applies when a global serializer is set up in the cluster configuration. Thus, you need to make your session objects Serializable to make it work.

You can also find this requirement in the documentation: https://github.com/hazelcast/hazelcast-tomcat-sessionmanager#features-and-requirements

I've raised a Github issue on the repo regarding this request, please track the process from there: https://github.com/hazelcast/hazelcast-tomcat-sessionmanager/issues/38




回答2:


Adding Kryo to the global serializer didn't work for me. I had to add it as a regular serializer. Spring boot example:

Config config = new Config();
/* other hazelcast configs omittedfor brevity */
SerializerConfig kyroSerizlier = new SerializerConfig()
                .setImplementation(new GlobalKryoSerializer())
                .setTypeClass(Object.class);
config.getSerializationConfig().addSerializerConfig(kyroSerizlier);


来源:https://stackoverflow.com/questions/48428131/hazelcast-with-global-serializer-kryo-there-is-no-suitable-de-serializer-for

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!