Deserialization attempt freezes program execution

Q

Qu0ll

In the following code I have an array of bytes in "bytes" which is the
serialization of a class of type MyClass. When I try to deserialize the
bytes, it gets as far as the call to readObject() and then just stops. No
exception is thrown.

What could possibly cause the execution to stop at that point?

ByteArrayInputStream bais = new ByteArrayInputStream(bytes, 0,
bytes.length);
MyClass mc = null;
try {
ObjectInputStream ois = new ObjectInputStream(bais);
System.out.println("Reading object...");
Object o = ois.readObject();
System.out.println("Object read, o = " + o + ".");
mc = (MyClass)o;
}
catch (Exception cnfe) {
System.out.println("Exception!");
cnfe.printStackTrace();
}

--
And loving it,

-Q
_________________________________________________
(e-mail address removed)
(Replace the "SixFour" with numbers to email me)
 
Q

Qu0ll

I have now been informed that the code I posted previously is not entirely
accurate. What's actually happening is that there is an interface
MyInterface which MyClass implements. An object of type MyClass is being
serialized on one machine and transmitted to another where MyClass is not
known explicitly. The hope was that the serialized object would contain
sufficient information so that referring to the deserialized object as a
MyInterface would be sufficient to allow the object to be deserialized on
the second machine.

Is this correct? Does the MyClass need to be on the class path of the
second machine in order for an object of type MyInterface to be deserialized
there?

If so, is there a way to dynamically instantiate the class object of MyClass
on the second machine so that it could "learn" about this class?

Revised code:

ByteArrayInputStream bais = new ByteArrayInputStream(bytes, 0,
bytes.length);
MyInterface mi = null;
try {
ObjectInputStream ois = new ObjectInputStream(bais);
System.out.println("Reading object...");
Object o = ois.readObject();
System.out.println("Object read, o = " + o + ".");
mi = (MyInterface)o;
}
catch (Exception cnfe) {
System.out.println("Exception!");
cnfe.printStackTrace();
}

--
And loving it,

-Q
_________________________________________________
(e-mail address removed)
(Replace the "SixFour" with numbers to email me)
 
S

Silvio Bierman

Qu0ll said:
I have now been informed that the code I posted previously is not
entirely accurate. What's actually happening is that there is an
interface MyInterface which MyClass implements. An object of type
MyClass is being serialized on one machine and transmitted to another
where MyClass is not known explicitly. The hope was that the serialized
object would contain sufficient information so that referring to the
deserialized object as a MyInterface would be sufficient to allow the
object to be deserialized on the second machine.

Is this correct? Does the MyClass need to be on the class path of the
second machine in order for an object of type MyInterface to be
deserialized there?

If so, is there a way to dynamically instantiate the class object of
MyClass on the second machine so that it could "learn" about this class?

Revised code:

ByteArrayInputStream bais = new ByteArrayInputStream(bytes, 0,
bytes.length);
MyInterface mi = null;
try {
ObjectInputStream ois = new ObjectInputStream(bais);
System.out.println("Reading object...");
Object o = ois.readObject();
System.out.println("Object read, o = " + o + ".");
mi = (MyInterface)o;
}
catch (Exception cnfe) {
System.out.println("Exception!");
cnfe.printStackTrace();
}

No, this will not work. The actual class has to be known. Serialized
objects only contain their class name, not the definition. Beware of
class version issues as well.

Silvio Bierman
 
S

Silvio Bierman

Qu0ll said:
I have now been informed that the code I posted previously is not
entirely accurate. What's actually happening is that there is an
interface MyInterface which MyClass implements. An object of type
MyClass is being serialized on one machine and transmitted to another
where MyClass is not known explicitly. The hope was that the serialized
object would contain sufficient information so that referring to the
deserialized object as a MyInterface would be sufficient to allow the
object to be deserialized on the second machine.

Is this correct? Does the MyClass need to be on the class path of the
second machine in order for an object of type MyInterface to be
deserialized there?

If so, is there a way to dynamically instantiate the class object of
MyClass on the second machine so that it could "learn" about this class?

Revised code:

ByteArrayInputStream bais = new ByteArrayInputStream(bytes, 0,
bytes.length);
MyInterface mi = null;
try {
ObjectInputStream ois = new ObjectInputStream(bais);
System.out.println("Reading object...");
Object o = ois.readObject();
System.out.println("Object read, o = " + o + ".");
mi = (MyInterface)o;
}
catch (Exception cnfe) {
System.out.println("Exception!");
cnfe.printStackTrace();
}

You could implement a class loading scheme on the receiving side and
find a way of getting the current class definition over from the sending
side. Class version issues are still a risk as long as process lifetimes
on both ends are not coupled.

Regards,

Silvio Bierman
 
G

Gordon Beaton

In the following code I have an array of bytes in "bytes" which is the
serialization of a class of type MyClass. When I try to deserialize the
bytes, it gets as far as the call to readObject() and then just stops. No
exception is thrown.

What could possibly cause the execution to stop at that point?

Exactly how did you create the byte array? I'll guess that it doesn't
contain both the necessary ObjectStream header and a valid object.

In another post you mention that the object's class is not known at
the receiving end. I'd expect that to cause an exception, not a hang.
On the other hand, your explicit cast to MyClass implies that MyClass
*is* known here.

/gordon

--
 
R

Roedy Green

What could possibly cause the execution to stop at that point?
To answer that question we need to see the declaration of the class
you serialised and the code you used to serialised it.
 
R

Roedy Green

The hope was that the serialized object would contain
sufficient information so that referring to the deserialized object as a
MyInterface would be sufficient to allow the object to be deserialized on
the second machine.

You must have the code for the deserialising class available to the
JVM doing the deserialising. In practical terms, it has bloody well
better be the exact same code used to serialise the object though in
theory some mismatches are possible.

see http://mindprod.com/jgloss/serialization.
 
D

Daniel Pitts

Qu0ll said:
I have now been informed that the code I posted previously is not
entirely accurate. What's actually happening is that there is an
interface MyInterface which MyClass implements. An object of type
MyClass is being serialized on one machine and transmitted to another
where MyClass is not known explicitly. The hope was that the serialized
object would contain sufficient information so that referring to the
deserialized object as a MyInterface would be sufficient to allow the
object to be deserialized on the second machine.

Is this correct? Does the MyClass need to be on the class path of the
second machine in order for an object of type MyInterface to be
deserialized there?

If so, is there a way to dynamically instantiate the class object of
MyClass on the second machine so that it could "learn" about this class?

Revised code:

ByteArrayInputStream bais = new ByteArrayInputStream(bytes, 0,
bytes.length);
MyInterface mi = null;
try {
ObjectInputStream ois = new ObjectInputStream(bais);
System.out.println("Reading object...");
Object o = ois.readObject();
System.out.println("Object read, o = " + o + ".");
mi = (MyInterface)o;
}
catch (Exception cnfe) {
System.out.println("Exception!");
cnfe.printStackTrace();
}
This doesn't work with Serialization, but it would work with RMI. Keep
in mind that with RMI, the method calls actually go through the "wire",
so all the implementation details are held in the original machine.
 
Q

Qu0ll

<snip>

OK, thanks to all those who replied and to Roedy for the excellent resource
on serialization. So clearly what I am trying to do is not possible but is
there some way to transmit the class definition along with or separately
from the actual object itself? Basically I am trying to keep the client
very small and only load classes when they are needed as the client is an
applet. I also understand that applets cannot use custom class loaders.

Any ideas?

--
And loving it,

-Q
_________________________________________________
(e-mail address removed)
(Replace the "SixFour" with numbers to email me)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top