user5479362
user5479362

Reputation:

How to define the serialization id of the DefaultListableBeanFactory?

I've got the serialization error with DefaultListableBeanFactory:

Caused by: java.io.NotSerializableException: DefaultListableBeanFactory has no serialization id
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.writeReplace(DefaultListableBeanFactory.java:1523)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at java.io.ObjectStreamClass.invokeWriteReplace(ObjectStreamClass.java:1118)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1136)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1378)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
  at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
  at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
  at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
  at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
  at org.apache.catalina.session.StandardSession.writeObject(StandardSession.java:1673)
  at org.apache.catalina.session.StandardSession.writeObjectData(StandardSession.java:1079)
  at org.apache.catalina.session.StandardManager.doUnload(StandardManager.java:432)
  at org.apache.catalina.session.StandardManager.unload(StandardManager.java:353)
  at org.apache.catalina.session.StandardManager.stopInternal(StandardManager.java:518)
  at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
  at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5622)
  at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232)
  at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1575)
  at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1564)
  ... 4 more

After inspecting the code I've found out, that the class code requires some arbirtrary serialization id to be set somewhere:

protected Object writeReplace() throws ObjectStreamException {
    if (this.serializationId != null) {
        return new SerializedBeanFactoryReference(this.serializationId);
    }
    else {
        throw new NotSerializableException("DefaultListableBeanFactory has no serialization id");
    }
}

I'm not setting that serializationId, and I haven't found out, how can I set it. I suppose, something is missing in my spring xml :

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    ">

    <context:component-scan base-package="com.example.beans"/>

</beans>    

The singleton beans are made serializable using aop scoped proxy:

@Component
@Scope(proxyMode = ScopedProxyMode.INTERFACES) 
public class DatabaseAPIImpl implements DatabaseAPI {

but obviously, something is wrong with that proxy and some crucial informations are not set. What I am missing here? What should I set so that the DefaultListableBeanFactory is properly initialized?

Upvotes: 0

Views: 1937

Answers (1)

Daniel Facciabene
Daniel Facciabene

Reputation: 101

I had a similar problem and solved it doing this:

  @Component
  public class SessionFixBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
      private static final String SERIALIZATION_ID = "4086d293-966c-4d89-8485-f1c1f5c09218";

      @Override
      public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
          if ((beanFactory instanceof DefaultListableBeanFactory)) {
              DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
              dlbf.setSerializationId(SERIALIZATION_ID);
          }
      }
  } 

You may want to read this question: https://github.com/spring-projects/spring-session/issues/799

Upvotes: 1

Related Questions