Frage

I have serialized a HashTable<String,Object> object using an ObjectOutputStream. When serializing the object, I get no exception, but upon deserialization, the following exception occurs:

Exception in thread "main" java.io.InvalidClassException: java.lang.Long; local class
incompatible: stream classdesc serialVersionUID = 4290774032661291999, local class
serialVersionUID = 4290774380558885855

I no longer get the error when I remove all of the keys in the HashTable that have a value that is not a String (all of the key / value pairs I removed had a primitive type as their value).

What could be causing this error?

UPDATE - Here's the code

public static String serialize(Quiz quiz) throws IOException{
    HashMap<String,Object> quizData = new HashMap<String,Object>();
    quizData.put("version", 0); //int
    quizData.put("name", quiz.getName()); //String
    quizData.put("desc", quiz.getDesc()); //String
    quizData.put("timelimitType", quiz.getTimelimitType()); //String
    quizData.put("timelimit", quiz.getTimelimit()); //long
    ArrayList<String> serializedQuestionsData = new ArrayList<String>();
    for (Question question : quiz.getQuestions())
        serializedQuestionsData.add(Question.serialize(question));
    quizData.put("questions", serializedQuestionsData.toArray(new String[0])); //String[]
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos;
    try { oos = new ObjectOutputStream(baos); } catch (IOException error){ throw error; }
    try { oos.writeObject(quizData); } catch (IOException error){ throw error; }
    return baos.toString();
}
@SuppressWarnings("unchecked")
public static Quiz deserialize(String serializedQuizData) throws IOException, ClassNotFoundException{
    ByteArrayInputStream bais = new ByteArrayInputStream(serializedQuizData.getBytes());
    ObjectInputStream ois;
    try { ois = new ObjectInputStream(bais); } catch (IOException error){ throw error; }
    HashMap<String,Object> quizData;
    // Exception occurs on the following line!!
    try { quizData = (HashMap<String,Object>) ois.readObject(); } catch (ClassNotFoundException error){ throw error; }
    Quiz quiz;
    if ((int) quizData.get("version") == 0){
        quiz = new Quiz((String) quizData.get("name"),
                (String) quizData.get("desc"),
                (String) quizData.get("timelimitType"),
                (long) quizData.get("timelimit"));
        for (String serializedQuestionData : (String[]) quizData.get("questions"))
            quiz.addQuestion(Question.deserialize(serializedQuestionData));
    } else {
        throw new UnsupportedOperationException("Unsupported version: \"" + quizData.get("version") + "\"");
    }
    return quiz;
}
War es hilfreich?

Lösung

The problem is that you're transforming a byte array output stream to a String using toString(). The toString() method simply uses the platform default encoding to transform the bytes (which do not represent characters at all but are purely binary data) into a String. This is thus a lossy operation, because your platform default encoding doesn't have a valid character for every possible byte.

You shouldn't use String to hold binary data. A String contains characters. If you really need a String, then encode the byte array using a Hexadecimal or Base64 encoder. Otherwise, simply use a byte array to hold your binary data:

public static byte[] serialize(Quiz quiz) throws IOException{
    ...
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ...
    return baos.toByteArray();
}

@SuppressWarnings("unchecked")
public static Quiz deserialize(byte[] serializedQuizData) throws IOException, ClassNotFoundException{
    ByteArrayInputStream bais = new ByteArrayInputStream(serializedQuizData);
    ...
    return quiz;
}

Andere Tipps

The only explanation I can think of is that is that something is corrupting your object stream between you reading it and writing it. The serialVersionID in "the local class) (4290774380558885855) is standard across all Java implementations that try to be compatible with Java (tm). The source code for java.lang.Long says that that serial version id has not changed since Java 1.0.2.

If you need further help, you will need to provide an SSCCE that covers both creation and reading of the serialized object.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top