0

我的应用程序有大量域对象,它们通过spring-session被序列化到Redis存储中。我试图使用Kryo(4.0.0)进行自动序列化,而不使对象明确可序列化。kryo序列化 - Java序列化期间的错误

我在尝试序列化尚未实现的对象Serializable时收到以下错误。

com.esotericsoftware.kryo.KryoException: Error during Java serialization. 
    com.esotericsoftware.kryo.serializers.JavaSerializer.write(JavaSerializer.java:51) 
    com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:651) 
    org.springframework.session.data.redis.KryoObjectSerializer.serialize(KryoObjectSerializer.java:51) 
    org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:168) 
    org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:129) 
    org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:86) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:778) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:670) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:388) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:245) 
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245) 
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217) 
    org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170) 
    org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) 
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 
JBWEB000071: root cause 

java.io.NotSerializableException: mypck.UserDomain 
    java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) 
    java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
    java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
    java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
    java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
    java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
    java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
    java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
    java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
    java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
    java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
    java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
    java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
    java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) 
    com.esotericsoftware.kryo.serializers.JavaSerializer.write(JavaSerializer.java:48) 
    com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:651) 
    org.springframework.session.data.redis.KryoObjectSerializer.serialize(KryoObjectSerializer.java:51) 
    org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:168) 
    org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:129) 
    org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:86) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:778) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:670) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:388) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:245) 
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245) 
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217) 
    org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170) 
    org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) 
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 

我KRYO初始化:

private Kryo getInstance() { 
    Kryo kryo = new Kryo() { 
      @Override 
      public Serializer<?> getDefaultSerializer(final Class type) { 
       if (AbstractPersistentCollection.class.isAssignableFrom(type)) { 
        return new BeanSerializer(this, type); 
       } else if (Serializable.class.isAssignableFrom(type)) { 
        return new JavaSerializer(); 
       } 

       return super.getDefaultSerializer(type); 
      } 
      }; 

      kryo.setInstantiatorStrategy(new SerializingInstantiatorStrategy()); 

    return kryo; 
} 

更新1:

com.esotericsoftware.kryo.KryoException: Error during Java serialization. 
Serialization trace: 
authentication (org.springframework.security.core.context.SecurityContextImpl) 
    com.esotericsoftware.kryo.serializers.JavaSerializer.write(JavaSerializer.java:51) 
    com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:575) 
    com.esotericsoftware.kryo.serializers.ObjectField.write(ObjectField.java:80) 
    com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:505) 
    com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:651) 
    org.springframework.session.data.redis.KryoObjectSerializer.serialize(KryoObjectSerializer.java:52) 
    org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:168) 
    org.springframework.data.redis.core.DefaultHashOperations.putAll(DefaultHashOperations.java:129) 
    org.springframework.data.redis.core.DefaultBoundHashOperations.putAll(DefaultBoundHashOperations.java:86) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:778) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:670) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:388) 
    org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:245) 
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245) 
    org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217) 
    org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170) 
    org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) 
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 
JBWEB000071: root cause 

java.io.NotSerializableException: mypkg.UserDomain 
    java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) 
    java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
    java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
    java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 
    java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 
    java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 
    java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 
+0

可能有更多的例外,这里没有显示..你能展示更多吗? – theBeacon

+0

@theBeacon更新。 – Charith

+0

'java.io.NotSerializableException:mypck.UserDomain'的部分内容你不明白吗? – EJP

回答

1

由于使用Java serializer(从异常清零),您mypck.UserDomain类必须实现serializableExternalizable

从文档

KRYO的JavaSerializer并使用标准Java序列化来代替。 这种方法与通常的Java序列化一样缓慢,但只要Java序列化能够对其进行序列化,就会使您的类序列化。当然,您的班级应该实施可序列化的 或Externalizable接口,这是通常的Java 序列化所要求的。

异常的原因是

你可能一直在努力composite object,其中container classserializable但alteast的contained class一个不serializable

Kyro获取您传递给Kryo.writeObject(...) API的对象的序列化程序。

此外,删除

如果对象类,它的对象,你在Kryo.readObject(...)通过不执行serializable

更好,删除此ryo.setInstantiatorStrategy(new SerializingInstantiatorStrategy()); 将无法​​正常工作,现在所有的串行化将被KRYO (统一)完成

public Serializer<?> getDefaultSerializer(final Class type) { 
     if (AbstractPersistentCollection.class.isAssignableFrom(type)) { 
      return new BeanSerializer(this, type); 
      } else if (Serializable.class.isAssignableFrom(type)) { 
      return new JavaSerializer(); 
     } 
    } 
+0

这正是我的问题。我认为Kyro可以为我自动选择正确的序列号(如果我的理解是正确的)。我不强制Java序列化。 – Charith

+1

在回答 – theBeacon

+0

解释我想你是对的。删除Instantiator,我可以看到SecurityContextImpl组成这些对象。 SecurityContextImpl是可序列化的,但我的用户域对象不是。用户域对象有许多对象连接到它。有些是可序列化的,有些则不是。你能提出一个解决方案吗?更新错误的问题。 – Charith