InvalidClassException:对于反序列化,类无效

时间:2011-04-18 12:57:12

标签: java

我在我的项目中使用SSA解析器库。当我使用命令提示符调用其中一个类的main方法时,它在我的机器上正常工作。

我从命令提示符执行以下命令:

java -Xmx800M -cp %1 edu.stanford.nlp.parser.lexparser.LexicalizedParser -retainTMPSubcategories -outputFormat "penn,typedDependenciesCollapsed"   englishPCFG.ser.gz %2

但是当我尝试在我的java程序中使用相同的类时,我得到Caused by: java.io.InvalidClassException: edu.stanford.nlp.stats.Counter; edu.stanford.nlp.stats.Counter; class invalid for deserialization异常。

以下行抛出错误:

LexicalizedParser _parser = new LexicalizedParser("C:\englishPCFG.ser.gz");

englishPCFG.ser.gz 文件包含在创建LexicalizedParser类型的对象时加载的一些类或信息。

以下是stacktrace:

Loading parser from serialized file C:\englishPCFG.ser.gz ...
Exception in thread "main" java.lang.RuntimeException: Invalid class in file: C:\englishPCFG.ser.gz
    at edu.stanford.nlp.parser.lexparser.LexicalizedParser.getParserDataFromSerializedFile(LexicalizedParser.java:822)
    at edu.stanford.nlp.parser.lexparser.LexicalizedParser.getParserDataFromFile(LexicalizedParser.java:603)
    at edu.stanford.nlp.parser.lexparser.LexicalizedParser.<init>(LexicalizedParser.java:168)
    at edu.stanford.nlp.parser.lexparser.LexicalizedParser.<init>(LexicalizedParser.java:154)
    at com.tcs.srl.ssa.SSAInvoker.<init>(SSAInvoker.java:21)
    at com.tcs.srl.ssa.SSAInvoker.main(SSAInvoker.java:53)
Caused by: java.io.InvalidClassException: edu.stanford.nlp.stats.Counter; edu.stanford.nlp.stats.Counter; class invalid for deserialization
    at java.io.ObjectStreamClass.checkDeserialize(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.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 edu.stanford.nlp.parser.lexparser.LexicalizedParser.getParserDataFromSerializedFile(LexicalizedParser.java:814)
    ... 5 more
Caused by: java.io.InvalidClassException: edu.stanford.nlp.stats.Counter; class invalid for deserialization
    at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    ... 17 more

我是Java世界的新手,所以我不知道为什么会出现这个错误,我该怎么办才能避免它。

我用Google搜索了这个错误,然后我发现这个错误是因为某些版本不匹配,我认为这类似于dll地狱的Windows API。我对么?

任何人都知道为什么会出现这种错误?我们该怎么办才能避免呢?

请指教!!!

5 个答案:

答案 0 :(得分:9)

可能是因为classe的serialVersionUID发生了变化,并且您正在尝试读取使用该类的其他版本编写的对象。

您可以通过在序列化类中使用serialVersionUID来强制版本号:

private static final long serialVersionUID = 1L;

答案 1 :(得分:8)

dll hell 的java字是 classpath hell ;-)但是那不是你的地狱。

对象序列化是将java对象持久化到文件(或流)的过程。输出格式为二进制。反序列化(iaw:从序列化数据制作java对象)需要相同版本的类。

因此,您可以只使用该Counter类的较旧版本或较新版本。此输入文件应附带一份文档,清楚地说明需要哪个版本的解析器。我先调查那个方向。

答案 2 :(得分:1)

OT:为了完整起见,我在解决另一个问题时遇到了InvalidClassException ... class invalid for deserialization(和这个问题)。 (由于edu.stanford.nlp.stats.Counter不是匿名的,因此这个问题的情况肯定与我的情况不同。)

我从服务器向客户端发送了一个序列化类,该类有两个匿名类。具有这些类的jar在服务器和客户端之间共享,但对于服务器,它是在Eclipse JDT中编译的,用于javac中的客户端。编译器为匿名类生成了名称$ 1,$ 2的不同顺序,因此服务器发送了$ 1的实例,但在客户端无法收到$ 1。 blogpost中的更多信息(捷克语中的例子很明显)。

答案 3 :(得分:0)

尝试使用serialVer生成您尝试反序列化的旧类的serialID并将其显式添加(private static final long serialVersionUID =(在此处插入来自serialVer的数字)L;)该类的新版本。如果您更改了序列化类中的任何内容并且尚未设置serialID,则java认为您序列化的类与新类不兼容。

答案 4 :(得分:0)

此错误表明C:\ englishPCFG.ser.gz中的序列化对象是使用较旧或较新的类定义进行序列化的,不幸的是,这种定义在某种程度上违反了兼容序列化的条款到另一个。

请参阅http://download.oracle.com/javase/1.4.2/docs/api/java/io/InvalidClassException.html

您是否可以检查生成此文件的时间,然后在创建时找到SSAParser库的版本?