Deserialization attempt freezes program execution

Discussion in 'Java' started by Qu0ll, Feb 18, 2008.

  1. Qu0ll

    Qu0ll Guest

    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
    _________________________________________________

    (Replace the "SixFour" with numbers to email me)
    Qu0ll, Feb 18, 2008
    #1
    1. Advertising

  2. Qu0ll

    Qu0ll Guest

    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
    _________________________________________________

    (Replace the "SixFour" with numbers to email me)
    Qu0ll, Feb 19, 2008
    #2
    1. Advertising

  3. Qu0ll wrote:
    > 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
    Silvio Bierman, Feb 19, 2008
    #3
  4. Qu0ll wrote:
    > 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
    Silvio Bierman, Feb 19, 2008
    #4
  5. On Tue, 19 Feb 2008 09:23:26 +1100, Qu0ll wrote:
    > 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

    --
    Gordon Beaton, Feb 19, 2008
    #5
  6. Qu0ll

    Roedy Green Guest

    On Tue, 19 Feb 2008 09:23:26 +1100, "Qu0ll" <>
    wrote, quoted or indirectly quoted someone who said :

    >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.
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Feb 19, 2008
    #6
  7. Qu0ll

    Roedy Green Guest

    On Tue, 19 Feb 2008 11:29:36 +1100, "Qu0ll" <>
    wrote, quoted or indirectly quoted someone who said :

    >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.
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Feb 19, 2008
    #7
  8. Qu0ll

    Daniel Pitts Guest

    Qu0ll wrote:
    > 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.

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Feb 19, 2008
    #8
  9. Qu0ll

    Qu0ll Guest

    "Qu0ll" <> wrote in message
    news:47ba055e$0$30976$...

    <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
    _________________________________________________

    (Replace the "SixFour" with numbers to email me)
    Qu0ll, Feb 20, 2008
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    640
    Sahil Malik
    May 14, 2004
  2. setar
    Replies:
    21
    Views:
    1,142
    Robert Klemme
    Sep 20, 2006
  3. Replies:
    9
    Views:
    359
    junaidnaseer
    May 10, 2006
  4. Andreas Røsdal

    Multithreaded python program freezes

    Andreas Røsdal, Dec 20, 2009, in forum: Python
    Replies:
    1
    Views:
    410
    Cameron Simpson
    Dec 21, 2009
  5. GMI
    Replies:
    3
    Views:
    495
    Tad McClellan
    Jun 19, 2005
Loading...

Share This Page