Java SerialIzation:反序列化Object时的'ClassNotFoundException'

时间:2013-08-20 09:49:38

标签: java oop serialization deserialization

错误:

  

java.lang.ClassNotFoundException:testprocedure.tp $ 3       在java.net.URLClassLoader $ 1.run(未知来源)       在java.net.URLClassLoader $ 1.run(未知来源)       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 Source)       at java.io.ObjectInputStream.readObject0(Unknown Source)       at java.io.ObjectInputStream.readObject(Unknown Source)       at core.ProcedureSetup.load(ProcedureSetup.java:57)     在core.Engine.main(Engine.java:25)

我实例化对象并从Class“tp”调用“ProcedureSetup”的“save”方法。

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

然而,我从不同的程序集合加载,这些程序具有-ALL-所需的代码但是“tp”

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

在课堂上保存和加载对象:

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) {}
    }

}

我的问题是:

为什么会发生这些错误?

为什么(如果有必要)我需要在类路径中使用“tp”?

如果实际上有一种方法可以将对象保存在当前状态而不需要在类路径中使用“tp”,那么我该如何去做呢? (链接会很可爱)

3 个答案:

答案 0 :(得分:2)

当您读入序列化对象时,Java会通过使用序列化流中的信息来“重建”它,以构建对象的实时副本。除非它具有对象类的.class文件,否则它不能这样做;它需要一个空白副本来“填写”来自流的信息。

最好的选择通常是确保类在类路径上。如果你有一些特殊的原因导致它不起作用,Java序列化不适合你;相反,JSON可能是一个合适的选择。

答案 1 :(得分:1)

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

以上是您的tp课程的匿名内部课程。因此,要进行反序列化,这个匿名内部类及其封闭类tp必须存在于类路径中:字节流包含类的名称和对象的字段,但它不包含包含类本身的字节码。

您应该将其设为顶级课程,或者至少是静态内部课程。

您还应该尊重Java命名约定:类是CamelCased。

答案 2 :(得分:0)

  

为什么会发生这些错误?

此处只有一个错误:java.lang.ClassNotFoundException: testprocedure.tp$3。这意味着您尚未将testprocedure/tp$3.class部署到对等方。

  

为什么(如果有必要)我需要在类路径中使用“tp”?

这样反序列化就可以成功。对于没有.class文件的类,你不能做任何事情,更不用说反序列化它的实例了。