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