• Post Reply Bookmark Topic Watch Topic
  • New Topic

Serialization and ClassCastException  RSS feed

 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Class A has a member variable of type class B. Both A and B are serializable.

A program can serialize and deserialze class B with no problem. However, a program that serializes class A cannot turn right around and deserialize it: a ClassCastException is throws when member variable B is reached. I can't post the actual code, as it's propriety.

Any thoughts?
 
paul wheaton
Trailboss
Posts: 22580
Firefox Browser IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Could it be a versioning thing? That seems to be 90% of serialization problems: the class on both sides has the same name but one side has a slightly older version.

By any chance, is either of your applications an applet?
 
Michael Ernest
High Plains Drifter
Sheriff
Posts: 7292
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oy, this is sounding familiar but it's a distant echo of a memory...I'll play for a second here and see if that jogs the mind.
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for taking an interest. Unfortunately, it's not a versioning thing: line number 1 of the code serializes, line number 2 deserializes, then kaboom. I tried to write some code to reproduce the error in an example class, but so far, zip. I'm totally stumped

M
 
David O'Meara
Rancher
Posts: 13459
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm trying to imagine how it would create the outcome you're seeing, but are you working with a single or multiple ClassLoaders?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's not clear to me how your last post establishes that there's not a versioning problem of some sort. Unless you mean that you checked this carefully, though the details of the check are not shown here.

Are the serialization and deserialization occurring in the same VM? Is there any possiblity that class B is being loaded by two different class loaders, maybe even using different Jar files? It may be worthwhile to check your classpaths very carefully.

You might try changing JDks a bit, to see if maybe there's just a bug in the current version you're using.
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
It's not clear to me how your last post establishes that there's not a versioning problem of some sort. Unless you mean that you checked this carefully, though the details of the check are not shown here.

I'm pretty sure this isn't the problem: the pseudo code for the process follows. There's no threading, or anything fancy going on.

line 1: serializeA(a,"A.ser");
line 2: A aTmp = (A)serializeA("A.ser");

Are the serialization and de serialization occurring in the same VM? Is there any possiblity that class B is being loaded by two different class loaders, maybe even using different Jar files?

Yes. No, no.

It may be worthwhile to check your classpaths very carefully.

Good suggestion: I tried this, but I didn't see anything weird.

You might try changing JDks a bit, to see if maybe there's just a bug in the current version you're using.[/QB]

I'll give it a shot, thanks.
[ June 30, 2004: Message edited by: Max Habibi ]
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by David O'Meara:
I'm trying to imagine how it would create the outcome you're seeing, but are you working with a single or multiple ClassLoaders?



Same class loaders, I'm afraid.

I'm with you: I haven't been able to recreate the problem in a sample class, and I can't share the original code, due to reasons that are too complicated to explain: I know I'm asking a lot here, but I've pretty much tried everything I can think of.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well congratulations, Max. You've got yourself a very weird problem.

I assume in your pseudocode above, line 2 should deserialize A.ser, is that right?

Does either A or B implement Externalizable? Are there readExternal() and writeExternal() methods somewhere in its hierarchy? If so, it sounds like there's a bug in one or the other.

More generally, are you using the serialization provided by ObjectOutputStream and ObjectInputStream, or something else - like say, XStream?

You say you can serialize and deserialize a B instance by itself. Are you sure you get back the same thing? Do

    originalB.equals(deserializedB)

and

    originalB.getClass() == deserializedB.getClass()

evaluate to true?

Where does the top of the stack trace from the ClassCastException point? Is it deep inside ObjectOutputStream's readObject()? Or somewhere else? Can you find the source for the line that's throwing the exceptio? Probably not if it's inside native code, but maybe you'll get lucky...

As an aside, it's a recurring annoyance that many exceptions thrown by library classes don't bother to include pertinent info. E.g. a FileNotFoundException usually won't include the name of the file you were looking for. Or in this case, a ClassCastException doesn't usually name the two classes involved. Which would be useful to know here. I'm sure there are other examples, though I don't remember them offhand. Of course that doesn't help you really; I jest felt like griping.

Good luck...
 
Max Habibi
town drunk
( and author)
Sheriff
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
Well congratulations, Max. You've got yourself a very weird problem.

Thanks, her mother and I are so proud.

I assume in your pseudocode above, line 2 should deserialize A.ser, is that right?

yes.

Does either A or B implement Externalizable? Are there readExternal() and writeExternal() methods somewhere in its hierarchy? If so, it sounds like there's a bug in one or the other.

no, no, thought I'm considering such as a solution.

More generally, are you using the serialization provided by ObjectOutputStream and ObjectInputStream, or something else - like say, XStream?

ObjectOutputStream and ObjectInputStream

You say you can serialize and deserialize a B instance by itself. Are you sure you get back the same thing? Do

    originalB.equals(deserializedB)

and

    originalB.getClass() == deserializedB.getClass()

evaluate to true?

Didn't think to check that: will do. What are you thinking here?

Where does the top of the stack trace from the ClassCastException point? Is it deep inside ObjectOutputStream's readObject()? Or somewhere else? Can you find the source for the line that's throwing the exceptio? Probably not if it's inside native code, but maybe you'll get lucky...

It seems to be at Class A#B, so I'm assuming it's where it actually tries to read B.

As an aside, it's a recurring annoyance that many exceptions thrown by library classes don't bother to include pertinent info. E.g. a FileNotFoundException usually won't include the name of the file you were looking for. Or in this case, a ClassCastException doesn't usually name the two classes involved.

Well, it does indicate that it's trying to cast it to a String: I'm guessing String is the default type it tries when it doesn't know what to do.
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've heard of cases where ClassCastException is thrown inappropriately if the serialized data stream is truncated. If B is small, and A is big, perhaps it's just that you need some stream-flushing someplace?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[JY]: You say you can serialize and deserialize a B instance by itself. Are you sure you get back the same thing? Do

originalB.equals(deserializedB)

and

originalB.getClass() == deserializedB.getClass()

evaluate to true?

[MH]: Didn't think to check that: will do. What are you thinking here?


Nothing very specific. We know there's a class cast exception for some reason, involving a B instance, so one of the questions I'd have is whether B is really the same B after deserialization. I guess I'm still clinging to ideas from discarded scenarios - e.g. a B that was loaded from a different jar file might not be the same B that we started with, even though the name is still B. Anyway, your comment that it's trying to cast to String seems to indicate this isn't the issue - the B is indeed a B, but for some reason it's being cast to String. Ooookay.

[JY]: Where does the top of the stack trace from the ClassCastException point? Is it deep inside ObjectOutputStream's readObject()? Or somewhere else? Can you find the source for the line that's throwing the exceptio? Probably not if it's inside native code, but maybe you'll get lucky...

[MH]: It seems to be at Class A#B, so I'm assuming it's where it actually tries to read B.


And that's the deepest part of the stack trace you can see? Hmmm... are there any stack trace elements referring to ObjectInputSTream or its helper classes? It might be worthwhile to study them, hopefully in conjunction with the appropriate source code, to see what exactly serialization is trying to do at this point. You could even post the relevant parts of the stack trace here, no? Along with the JDK version number you're using. You can excise references to the proprietary code involved. I'd like to get an idea what ObjectInputStream is "thinking" here.
 
Jeroen Wenting
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Max, maybe a dead horse (which should never be beaten except to tenderise the meat for cooking) but is the accesslevel of class B something that prevents it from being accessed by the JVM?
If the class is not public, maybe that might prevent it from serialisation (I'd guess the responsible classes in the JVM would need to access it but maybe cannot).

Just some rambling and speculation, but you might look along those lines if all else fails.

Remember: when the likely solution has been excluded the unlikely becomes more likely (free after Sir A.C. Doyle).
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!