"ClassCastException" for items in List after serialization
consider this code:
publicclass MyClassimplements Serializable{
publicdouble price = -1;
publicdouble volume = -1;
}
List list =new ArrayList<MyClass>();
while(!endOfData){
MyClass mc =new MyClass();
...
mc.price = x;
mc.volume = y;
list.add(mc);
}
ObjectOutputStream oos =new ObjectOutputStream(out);
oos.writeObject(list);
-
and then the receiver-side:
ObjectInputStream ois =new ObjectInputStream(in);
List list = (List) ois.readObject();
MyClass mc = (MyClass) list.get(2);
..... error ... error ...
Exception in thread "Thread-1" java.lang.ClassCastException: MyClass
note: using aDouble instead ofMyClass works ok.
also please notice:
ObjectInputStream ois =new ObjectInputStream(in);
List list = (List) ois.readObject();
Object mc = (Object) list.get(4);
System.out.println("this is what i am --> " + mc.getClass().getCanonicalName());
....
output: "this is what i am --> MyClass"
thanks.
Message was edited by:
suppon
[1771 byte] By [
suppona] at [2007-11-27 5:04:27]

# 2
this issue is ClassLoading
the MyClass objects are not
initially loaded in the receiver's JVM.
> Is MyClass the same at the sender and the receiver?
> Same .class file?
MyClass is loaded during the run-time. a
#diff of the my.jar files on client/server
shows its exactly the same file.
this is the ClassLoader code:
URLClassLoader myL = new URLClassLoader(searchPath);
Class class1 = myL.loadClass("MyClass");
List list = (List<MyClass>) ois.readObject();
MyClass item = (MyClass) class1.cast(list.get(7));
..... errorr ... error ...
when i test the Loader by using an incorrect name for the
jar file: /tmp/my.jar2, and then, in the run-time,
i get an expected:
ClassNotFoundException: MyClass
this is the KEY issue (i think)
why do i get
"ClassCastExceptions" ?
and not
"ClassNotFoundException"
?
this puzzles me the most.
MyClass must be loaded, right?
yet, its not Castable
regarding packages:
mc.getClass().getCanonicalName();
shows the packages are the same.
# 3
> the MyClass objects are not
> initially loaded in the receiver's JVM.
Make a custom class as:
public class CustomObjectInputStream extends ObjectInputStream {
private ClassLoader classLoader;
/** Creates a new instance of CustomObjectInputStream */
public CustomObjectInputStream(InputStream in, ClassLoader classLoader) throws IOException {
super(in);
this.classLoader = classLoader;
}
protected Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {
return Class.forName(desc.getName(), false, classLoader);
}
}
and use an instance of this class instead of the standard object inputstream to deserialize your object. You should pass the url class loader as an argument to the constructor of the custom object input stream. The reason is that the standard object inputstream only recognises classes that are "statically defined in the JAVA class path". (I quote the last text because I am not sure if I am using the right terminology, but I hope you understand what I mean.)
> why do i get
>
> "ClassCastExceptions" ?
> and not
> "ClassNotFoundException"
> ?
This must be because somehow you have a "static" class definition for MyClass anyway, otherwise you wouldn't be able to write the following code and have it compile:
MyClass item = (MyClass) class1.cast(list.get(7));
Apparently your "static" MyClass definition does not correspond with the MyClass definition in your .jar file.
You can only access a deserialized object of which the class definition is in a .jar file through reflection, unless you can cast it to an interface with a "static" definition.