简体   繁体   中英

Java SerialIzation: 'ClassNotFoundException' when deserializing an Object

The error:

java.lang.ClassNotFoundException: testprocedure.tp$3 at java.net.URLClassLoader$1.run(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at java.io.ObjectInputStream.resolveClass(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Sourc e) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at core.ProcedureSetup.load(ProcedureSetup.java:57) at core.Engine.main(Engine.java:25)

I instantiate the object and call the "ProcedureSetup"'s "save" method from Class "tp".

ProcedureSetup ps=new ProcedureSetup(new Procedure(){ public void doStuff(){ System.out.println("Stuff is being done"); }});
ps.save();

however I load from a different collection of programs that has -ALL- required code but "tp"

ProcedureSetup ps=new ProcedureSetup();
ps.load();

Object saving and loading within class:

public void load(){
    String path=Operator.persistentGetFile();//gets the file path
    ObjectInputStream ois=null;
    FileInputStream fin=null;
    ProcedureSetup temp=null;
    try {
        fin = new FileInputStream(path);
        ois = new ObjectInputStream(fin);
        temp=(ProcedureSetup) ois.readObject();
        ois.close();
        fin.close();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

    if(ois!=null){
        try {
            ois.close();
        } catch (IOException e) {}
    }
    if(fin!=null){
        try {
            fin.close();
        } catch (IOException e) {}
    }
    if(temp!=null){
        a=temp.a;
    }else{
        load();//If a load is failed, restart process.
    }
}

public void save(){
    String path=Operator.persistentGetDirectory();//get directory to save to
        String input =  JOptionPane.showInputDialog(this, "Enter the File name:");
        ObjectOutputStream oos=null;
        FileOutputStream fon=null;
        try {
            fon = new FileOutputStream(path+input+".obj");
            oos = new ObjectOutputStream(fon);
            try {
                oos.writeObject(this);
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            oos.close();
            fon.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
            if(oos!=null){
        try {
            oos.close();
        } catch (IOException e) {}
    }
    if(fon!=null){
        try {
            fon.close();
        } catch (IOException e) {}
    }

}

My questions are:

Why are these errors happening?

Why (if necessary) do I need to have "tp" in my classpath?

If there is in fact a way to save the object in its current state with out the necessity of "tp" in the classpath how would I go about doing that? (Links would be lovely)

When you read in a serialized object, Java "reconstitutes" it by using the information in the serialized stream to build a live copy of the object. It can't do this unless it has the .class file for the object's class; it needs a blank copy to "fill out" with the information from the stream.

The best option is usually to make sure that the class is on the class path. If you have some particular reason why this won't work, Java serialization isn't for you; JSON may be a suitable option instead.

new Procedure(){ public void doStuff(){ System.out.println("Stuff is being done"); }}

The above is an anonymous inner class of your tp class. So, to be deserialized, this anonymous inner class, and its enclosing class tp , must be present in the classpath: the stream of bytes contains the name of the class and the fields of the object, but it doesn't contain the byte-code of the class itself.

You should make it a top-level class, or at least a static inner class.

You should also respect the Java naming conventions: classes are CamelCased.

Why are these errors happening?

There is only one error here: java.lang.ClassNotFoundException: testprocedure.tp$3 . It means you haven't deployed testprocedure/tp$3.class to the peer.

Why (if necessary) do I need to have "tp" in my classpath?

So that deserialization can succeed. You can't do anything with a class you don't have the .class file for, let alone deserialize instances of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM