Page tree
Skip to end of metadata
Go to start of metadata

I recently worked on a project that used ExternalizableLite rather than POF for historical reasons.  Whilst this is slightly inefficient (complete class name is serialized) it works just fine.

However, I wanted to return a Map from an Aggregator and received the following stack trace :


Caused by: java.io.NotSerializableException: com.myclass.cachecore.data.Attribute$Factory         
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)         
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 java.util.HashMap.internalWriteEntries(HashMap.java:1777)         
at java.util.HashMap.writeObject(HashMap.java:1354)         
at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source)         
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)         
at java.lang.reflect.Method.invoke(Method.java:483)         
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)         
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)         
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 com.tangosol.util.ExternalizableHelper.writeSerializable(ExternalizableHelper.java:2485)         
at com.tangosol.util.ExternalizableHelper.writeObjectInternal(ExternalizableHelper.java:2973)         
at com.tangosol.util.ExternalizableHelper.serializeInternal(ExternalizableHelper.java:2903)         
at com.tangosol.util.ExternalizableHelper.toBinary(ExternalizableHelper.java:283)         
at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.partitionedService.PartitionedCache$ConverterValueToBinary.convert(PartitionedCache.CDB:3)         
at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.partitionedService.PartitionedCache$Storage.aggregateByProbe(PartitionedCache.CDB:89)         
at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.partitionedService.PartitionedCache.onAggregateFilterRequest(PartitionedCache.CDB:53) 

 So what is happening :

  1. Coherence goes to serialize the result of the Aggregator.
  2. It encounters HashMap which does not implement ExternalizableLite
  3. It defaults to Java serialization and traverses the object tree.
  4. It uses Java Serialization (since ExternalizableLite extends Serializable)
  5. It falls over since some static class is not Serializable.

Conclusion

  1. Use PortableObject if possible (more efficient)
  2. Its a pity that ExternalizableLite extends Serializable (but it won't be changed for backwards compatibility)
  3. Remove private static final long serialVersionUID = 1L; so Java Serialization cannot be used
  4. Make sure all objects returned implement ExternalizableLite
  5. Use PortableMap to solve the problem. 
  6. Same is true for HashSet use PortableSet
  • No labels