【问题标题】:kryo serialization - Error during Java serializationkryo 序列化 - Java 序列化期间的错误
【发布时间】:2017-02-04 04:43:52
【问题描述】:

我的应用程序有一堆域对象,它们通过 spring-session 序列化到 Redis 存储中。我正在尝试使用 Kryo (4.0.0) 进行自动序列化而不使对象显式可序列化。

我在尝试序列化尚未实现 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)

【问题讨论】:

  • 这里可能没有显示更多的异常.. 你能显示更多吗?
  • @theBeacon 已更新。
  • 'java.io.NotSerializableException: mypck.UserDomain' 的哪一部分你不明白?
  • @EJP 当我有可序列化的对象并且它具有不实现可序列化的复合对象时,我正在努力配置 kryo。简而言之,securitycontextimpl 由 spring security 管理,它具有身份验证对象,而该对象又具有此用户域对象(它不实现可序列化)。我正在使用 kryo 对通过 spring-session 保存到 redis 会话存储的对象进行隐式序列化。

标签: serialization hazelcast spring-session kryo spring-data-redis


【解决方案1】:

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

来自文档

Kryo 的 JavaSerializer 并改用标准的 Java 序列化。 这种方法与通常的 Java 序列化一样慢,但会 只要 Java 序列化能够让你的类序列化 序列化它。当然,你的类应该实现 Serializable 或通常 Java 所需的可外部化接口 序列化。

异常原因是

您可能一直在处理composite object,其中container classserializable,但contained class 的另外一个不是serializable

Kyro 采用您传递给Kryo.writeObject(...) API 的对象的类的序列化器。

另外,删除

ryo.setInstantiatorStrategy(new SerializingInstantiatorStrategy()); 如果您传入Kryo.readObject(...) 的对象的对象类没有实现serializable,则将无法工作

更好,去掉这个,现在所有的序列化都将由 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();
      } 
   }

【讨论】:

  • 这正是我的问题。我认为 Kyro 可以为我自动选择正确的序列化(如果我的理解是正确的)。我没有强制 java 序列化。
  • 在回答中解释
  • 我猜你是对的。删除了 Instantiator,我可以看到 SecurityContextImpl 正在组合这些对象。 SecurityContextImpl 是可序列化的,但我的用户域对象不是。用户域对象附有许多对象。有些是可序列化的,有些不是。你能建议一个解决方案吗?更新了问题的错误。
  • 删除 javaserializer
  • 正如我所提到的,可序列化在 spring security 提供的 securitycontextimpl 中实现。我无法删除它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2012-08-06
  • 1970-01-01
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多