2

Using Java's native serialization, I'm intermittently seeing ClassCastExceptions

java.lang.ClassCastException: myCompany.MyClass$MembershipServiceMethod cannot be cast to java.io.ObjectStreamClass

or (less frequently)

java.lang.ClassCastException: java.lang.String cannot be cast to java.io.ObjectStreamClass

when I deserialize objects of a particular immutable class. That is to say, the exception is always thrown for particular serialized representations, but most objects can be successfully serialized and deserialized.

public final class ServiceInteractionImpl implements ServiceInteraction, Serializable {
private static final long serialVersionUID = 1L;

private final InteractionSource source;
private final long startTime;
private final InteractionType type;
private final ServiceMethod method;
private final long duration;
private final String accompanyingMessage;

public ServiceInteractionImpl(final ServiceMethod method,
                                  final InteractionSource source,
                                  final InteractionType type,
                                  final long startTime,
                                  final long duration,
                                  final String accompanyingMessage) {
            this.source = source;
            this.startTime = startTime;
            this.duration = duration;
            this.type = type;
            this.method = method;
            this.accompanyingMessage = accompanyingMessage;
    }

    ...

    getters and canonical methods
}

where InteractionSource, InteractionType and ServiceMethod are enums. I can't replicate this in my local environment running junit tests that serialize and deserialize millions of objects.

Here is the writing code

    fileLock.lock();
    try {
        final File recordFile = new File(recordFileName);
        boolean appendToFile = false;

        if (recordFile.exists()) {
            appendToFile = true;
        }

        final OutputStream fileOutputStream = new FileOutputStream(recordFileName, true);
        final OutputStream buffer = new BufferedOutputStream(fileOutputStream);

        ObjectOutput output;
        if (appendToFile) {
            output = new AppendableObjectOutputStream(buffer);
        } else {
            output = new ObjectOutputStream(buffer);
        }

        int localSerializedInteractionsCount = 0;

        try {
            for (final ServiceInteraction interaction : tempCollection) {
                output.writeObject(interaction);
                output.flush();
                localSerializedInteractionsCount++;
                rollBackCollection.remove(interaction);
            }
        } finally {
            output.close();
            serializedInteractionCount += localSerializedInteractionsCount;
        }
    } catch (IOException e) {
        LOGGER.error("could not write to file", e);
        //some roll-back code
    } finally {
        fileLock.unlock();
    }

see Appending to an ObjectOutputStream for the AppendableObjectOutputStream

Any help much appreciated.

Community
  • 1
  • 1
Joffer
  • 1,921
  • 2
  • 21
  • 23
  • Reading between the lines here, I see two different run time environments - it fails in one, but runs in another. Details on diffs between environments? – Richard Sitze Sep 14 '12 at 05:50
  • @RichardSitze Just one runtime, but I've moved on from this issue and couldn't usefully participate in a discussion about it now. – Joffer Sep 17 '12 at 23:29

1 Answers1

0

If the class definition changed without updating serialVersionUID then its possible these errors are from stale object instances based on the old class definition.

thejosh
  • 137
  • 2