Archived

This forum has been archived. Please start a new discussion on GitHub.

One question about Ice 3.1.1 Manual

Ice 3.1.1 Manual, Page 918:
Unlike for exceptions, the sequence of type ID and slice pairs is not terminated by an empty ID.
But I can not find from Chapter "33.2.10 Exceptions" that exceptions's sequence of typeID and slice pairs is terminated by an empty ID. What's wrong?

However, I compare two versions of Ice Manual and find something:
Ice 3.1.1 Manual, Page 916
Following the header byte, the exception is marshaled as a sequence of pairs:
the first member of each pair is the type ID for an exception slice, and the second
member of the pair is a slice containing the marshaled members of that slice. The
sequence of pairs is marshaled in derived-to-base order, [COLOR="Red"]with the most-derived
slice first, and ending with the least-derived slice[/COLOR]. Within each slice, data members
are marshaled as for structures: in the order in which they are defined in the Slice
definition.

Ice 1.3.0 Manual, Page 470:
Following the header byte, the exception is marshaled as a sequence of pairs:
the first member of each pair is the type ID for an exception slice, and the second
member of the pair is a slice containing the marshaled members of that slice. The
sequence of pairs is marshaled in derived-to-base order, [COLOR="red"]with the most-derived
slice first, and ending with the least-derived slice. The sequence of pairs is terminated
by a single empty string.[/COLOR] Within each slice, data members are marshaled as
for structures: in the order in which they are defined in the Slice definition.

Does it mean that Ice protocol has changed a little sometime age ?

Comments

  • rc_hz wrote:
    Ice 3.1.1 Manual, Page 918:
    Unlike for exceptions, the sequence of type ID and slice pairs is not terminated by an empty ID.
    
    But I can not find from Chapter "33.2.10 Exceptions" that exceptions's sequence of typeID and slice pairs is terminated by an empty ID. What's wrong?

    The 3.1.1 manual is correct in that there is indeed no terminating empty ID at the end of the sequence of exception slices. However, the sentence you mention needs to be struck from the manual--it should not be there.

    Exception slices were originally intended to be terminated by an empty ID. The idea was that, with such a terminator, the receiver could tell when it receives an exception for which it recognizes none of the type IDs and could then throw a "no factory" exception.

    Unfortunately, I forgot to add the relevant line of code to the source, so the sequence of exception slices is in fact not terminated by an empty ID. (Sadly, I discovered this only after we had released the relevant Ice version.) In practice, this is not a big deal though: it means that, if a receiver gets an exception for which it recognizes none of the slice type IDs, it ends up trying to unmarshal yet another type ID (past the end of the sequence of received slices) and then gets an unmarshaling error and throws a MarshalException (instead of a "no exception factory" exception (which would have been a bit nicer).

    So, the 1.3.0 version described the intended marshaling, except that the code, in reality, never wrote the terminating empty ID.
    Does it mean that Ice protocol has changed a little sometime age ?

    No, the encoding has never changed. When I noticed the oversight, rather than adding the missing empty type ID, thereby creating an incompatible version of the encoding, I fixed the documentation to match reality. However, I only updated the section that describes the exception marshaling, not realizing that the section that describes the class marshaling also referred to this empty ID.

    So, here is the current real marshaling: for exceptions, the sequence of slices simply ends with the type ID of the base-most slice; for classes, the sequence of slices ends with the slice for "::Ice::Object". Neither sequence is terminated by an empty ID.

    As an aside, this reflects how Ice has evolved over time. If I were to re-create the encoding today, both exception and class slice sequences would be terminated by an empty ID. The reason that class slice sequences are terminated by "::Ice::Object" is that Ice::Object used to be a non-abstract class. However, now that Ice::Object is an abstract class, there is really no point in having this final slice--an empty type ID would be more compact. If we ever create a new version of the Ice encoding, I'll implement both changes.

    Now, because I'm curious... You are reading the protocol chapter in great detail, which tells me that you are probably doing something in-depth with the Ice protocol. We want to encourage use of the Ice protocol by others, and we'll do what we can to help independent implementation efforts. If you can share what you are doing, I'd be keen to hear what you are up to. And, of course, I'll do what I can to answer any questions.

    Cheers,

    Michi.
  •  Now, because I'm curious... You are reading the protocol chapter in
     great detail, which tells me that you are probably doing something
     in-depth with the Ice protocol. We want to encourage use of the Ice
     protocol by others, and we'll do what we can to help independent 
     implementation efforts. If you can share what you are doing, I'd be 
     keen to hear what you are up to. And, of course, I'll do what I can
     to answer any questions.
    
    Thanks for your kindness, Michi.
    Up to now, I am just a Ice lover and do some research in Ice's code and documentation in my spare time. I hope I can do some work based on Ice in future.


    1. I have noticed that MarshalException is thrown both at marshalling and unmarshalling steps and that there is no such an exception as UnmarshalException:
    //LocalException.ice
    /**
     *
     * This exception is a specialization of [ProtocolException] that is
     * raised upon an error during marshaling or unmarshaling data.
     *
     **/
    local exception MarshalException extends ProtocolException
    {
    };
    
    /**
     *
     * This exception is a specialization of [MarshalException] that is
     * raised if inconsistent data is received while unmarshaling a proxy.
     *
     **/
    local exception ProxyUnmarshalException extends MarshalException
    {
    };
    

    Is there any reason for this asymmetry ?


    2.Can you give some comment on this post ?
    http://www.zeroc.com/vbulletin/showthread.php?p=12027#post12027
  • rc_hz wrote:
    1. I have noticed that MarshalException is thrown both at marshalling and unmarshalling steps and that there is no such an exception as UnmarshalException:

    Well, yes, I guess, seeing that errors related to marshaling almost always happen during unmarshaling, I guess we could have called it UnmarshalException. At any rate, as is, MarshalException indicates something going wrong either on the sending side or the receiving side. In practice, 99.999% of the time, the exception will be raised by the receiving side.
    2.Can you give some comment on this post ?
    http://www.zeroc.com/vbulletin/showthread.php?p=12027#post12027
    Well, there really isn't anything I can add. People haven't exactly been breaking down the door demanding transaction support, so this is a low-priority project for the time being.

    Cheers,

    Michi.
  • marc
    marc Florida
    I simply chose "MarshalException" as the name for all exceptions that are related to the marshaling or reverse marshaling (unmarshaling) process. I couldn't think of a better name back then, and I can't think of a better name at present either (MarshalOrUnmarshalExcpetion seemed to be a bit long...).