开发者

InvalidClassException : class invalid for deserialization

开发者 https://www.devze.com 2023-02-26 04:29 出处:网络
I am using SSA parser library in my project. When I invoke main method of one of it\'s class using command prompt it works fine on my machine.

I am using SSA parser library in my project. When I invoke main method of one of it's class using command prompt it works fine on my machine.

I execute following command from command prompt :

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

But when I tried to use the same class in my java program, I am getting Caused by: java.io.InvalidClassEx开发者_Go百科ception: edu.stanford.nlp.stats.Counter; edu.stanford.nlp.stats.Counter; class invalid for deserialization exception.

Following line throws error :

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

This englishPCFG.ser.gz file contains some classes or information which gets loaded when creating object of type LexicalizedParser.

Following is the 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

I am new to Java world so I dont to why this error is coming and what should I do to avoid it.

I googled for this error then I found out that this error comes because of some version mismatch which I think is something similar to dll hell of windows API. Am I correct?

Anyone knows why this kind of error comes? and what should we do to avoid it?

Please enlighten !!!


It could be because the serialVersionUID of the classe has changed, and you are trying to read an object that was written with another version of the class.

You can force the version number by déclaring a serialVersionUID in your serializable class:

private static final long serialVersionUID = 1L;


The java word for dll hell is classpath hell ;-) But that's not your hell anyway.

Object serialization is a process of persisting java objects to files (or streams). The output format is binary. Deserialization (iaw: making java objects from serialized data) requires the same versions of the classes.

So it is possible, that you simply use an older or newer version of that Counter class. This input file should be shipped with a documentation that clearly says, which version of the parser is required. I'd investigate in that direction first.


OT: For the sake of completeness I ran into InvalidClassException ... class invalid for deserialization (and this question) when solving another problem. (Since edu.stanford.nlp.stats.Counter is not anonymous, the case in this question is certainly not the same case as mine.)

I was sending a serialized class from server to client, the class had two anonymous classes. The jar with these classes was shared among server and client but for server it was compiled in Eclipse JDT, for client in javac. Compilers generated different ordering of names $1, $2 for anonymous classes, hence instance of $1 was sent by server but could not be received as $1 at client side. More info in blogpost (in Czech, though example is obvious).


Try using serialVer to generate the serialID of your old classes that you're trying to de-serialize and add it explicitly (private static final long serialVersionUID = (insert number from serialVer here)L;) in the new versions of the class. If you change anything in a class serialized and you haven't setted the serialID, java thinks the class you've serialized isn't compatible with the new one.


This error suggests that the serialized objects within C:\englishPCFG.ser.gz were serialized with using a older or newer definition of the class which unfortunately is different in such a way that it breaks the terms of compatible serialization from one version to another.

Please see http://download.oracle.com/javase/1.4.2/docs/api/java/io/InvalidClassException.html

Can you check to see when this file was produced and then if possible locate the version of the SSAParser library at the time of it's creation?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号