Serialization in Java, invalid type code 00

前提是你 提交于 2019-12-29 08:41:47

问题


I'm getting an error (java.io.StreamCorruptedException: invalid type code: 00) when reading in a serialised object. Here is the class that implements serializable:

package guts;

import cc.mallet.classify.*;
import java.io.*;


public class NaiveBayesWithID implements Serializable  {

private NaiveBayes nb;
private static final long serialVersionUID = 1;
    private static final int CURRENT_SERIAL_VERSION = 1;

public NaiveBayesWithID(NaiveBayes nb) {
this.nb = nb;
}
public NaiveBayesWithID(){
this.nb = null;
}

    public void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    int version = in.readInt();
    if (version != CURRENT_SERIAL_VERSION)
        throw new ClassNotFoundException("Mismatched NaiveBayesTrainer versions: wanted " +
                CURRENT_SERIAL_VERSION + ", got " +
                version);

    //default selections for the kind of Estimator used

    NaiveBayesWithID test = (NaiveBayesWithID) in.readObject();
   // nb = test.returnNB();
    }

    public void writeObject(ObjectOutputStream out) throws IOException
    {
    out.writeInt(CURRENT_SERIAL_VERSION);

    //default selections for the kind of Estimator used
    out.writeObject(this);
    }

    public NaiveBayes returnNB(){
    return nb;
    }

    public void setNB(NaiveBayes nb){
        this.nb = nb;
    }

}

and here is the stack trace:

java.io.StreamCorruptedException: invalid type code: 00
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1355)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at java.util.ArrayList.readObject(ArrayList.java:593)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at cc.mallet.pipe.SerialPipes.readObject(SerialPipes.java:142)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at guts.NaiveBayesWithID.readObject(NaiveBayesWithID.java:29)
at controllers.Application.predict(Application.java:481)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:408)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:403)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:176)
at play.server.PlayHandler$NettyInvocation.execute(PlayHandler.java:169)
at play.Invoker$Invocation.run(Invoker.java:187)
at play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:149)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)

Does anyone know how I can get more information on the error? Or which object java is expecting?


回答1:


You have implemented a recursive writeObject method: when you write an instance to an output stream, it calls the writeObject method, which writes an int, and then writes the object to the output stream, which write an int, etc.

The goal of the serialVersionUID field is to check that the objects are compatible. It's done natively by the serialization mechanism. You don't have to do anything except changing the serialVersionUID value when the class changes.




回答2:


If the JVM cannot find the class when you attempt to read a serialized object, this exception will be generated. Check that updated jar/class files are available in the class path etc..

If you're running mallet from the command line, it may be looking at the unzipped mallet jars and class files from a downloaded distribution, and not at your nice new class files created in your downloaded source repository..

Don't feel too bad - I've seen this happen to others, and have done it myself (though I got a more informative "ClassNotFoundException" to help me figure it out :)




回答3:


Came here to find solution for Mallet classifier deserialization. Finally my problem was that I trained and serialized the model in one Eclipse project and tried to deserialize in another Eclipse project. One of the classes (among those I created) in the serialized object was only on the class path of the former project and not on the class path of the latter.




回答4:


Run to get the answer:

package so.java9217010;
import java.io.*;

public class SerializeMe implements Serializable{


    private String foo;
    private static final long serialVersionUID = 1;
    private static final int CURRENT_SERIAL_VERSION = 1;

    public SerializeMe(String foo) {
        this.foo = foo;
    }
    public SerializeMe(){
    }

    public SerializeMe readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        int version = in.readInt();
        if (version != CURRENT_SERIAL_VERSION)
            throw new ClassNotFoundException("Mismatched NaiveBayesTrainer versions: wanted " +
                    CURRENT_SERIAL_VERSION + ", got " +
                    version);

        //default selections for the kind of Estimator used

        return (SerializeMe) in.readObject();
        // nb = test.returnNB();
    }

    public void writeObject(ObjectOutputStream out) throws IOException
    {
        out.writeInt(CURRENT_SERIAL_VERSION);

        //default selections for the kind of Estimator used
        out.writeObject(this);
    }

    public String returnNB(){
        return foo;
    }

    public void setNB(String foo){
        this.foo = foo;
    }
    public static void main(String[] args) throws Exception {
        SerializeMe o = new SerializeMe("hello");
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oout = new ObjectOutputStream(bout);

        o.writeObject(oout);
        oout.flush();
        byte[] buff = bout.toByteArray();

        ByteArrayInputStream bin = new ByteArrayInputStream(buff);
        ObjectInputStream oin = new ObjectInputStream(bin);
        SerializeMe ro = o.readObject(oin);
        System.out.format(
                "got: %s -- the problem is most likely in the library you are using ...\n",
                      ro.returnNB());
    }
}


来源:https://stackoverflow.com/questions/9217010/serialization-in-java-invalid-type-code-00

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!