It is interesting to compare the Ice protocol and encoding with CORBA’s Inter-ORB Interoperability Protocol (IIOP) and Common Data Representation (CDR) encoding. The Ice protocol and encoding differ from IIOP and CDR in a number of important respects:
CDR supports both big-endian and little-endian encoding and provides a "receiver-makes-it-right" approach to byte ordering. The advantage of this is that, if sender and receiver have matching byte order, no reordering of the data is required at either end. However, the disadvantage is the additional complexity this creates in the marshaling logic. Moreover, the "receiver-makes-it-right" scheme carries a severe performance penalty if messages are to be forwarded via a number of intermediaries because this can require repeated unmarshaling, reordering, and remarshaling of messages. (Encapsulating the data would avoid this problem but, unfortunately, IIOP does not encapsulate most of the data that would benefit from it.)
• The CDR padding rules actually do not achieve any layout on natural word boundaries. For example, depending on its relative position in the enclosing data stream, the same structure value can differ in size and padding by up to seven bytes. There is not a single hardware platform in existence whose layout rules are the same as those of CDR. As a result, the padding bytes that are inserted serve no purpose other than to waste bandwidth.
• Data alignment rules greatly complicate data forwarding. For example, if the receiver of a data item wants to forward that data item to another down-stream receiver, it cannot just block-copy the received data into its transmit buffer because the padding of the data is sensitive to its relative position in the enclosing byte stream and a block copy would most likely result in an illegal encoding.
Due to the inability of CORBA vendors to agree on a common encoding for object references (the equivalent of Ice proxies), CORBA object references have a complex internal structure that is partially standardized and partially opaque, allowing vendors to add proprietary information to object references. In addition, to avoid object references getting too large, references that support more than one transport have a scheme for sharing the object identity among several transports instead of carrying multiple copies of the same identity. The encoding that is required to support all this machinery is quite complex and results in extremely poor marshaling performance when large number of object references are exchanged (for example, when using a trading service).
Versioning for IIOP and CDR was never designed properly, with the result that version negotiation in IIOP simply does not work. In particular, CDR encapsulations do not carry a separate version number. As a result, it is possible for data in encapsulations to travel to receivers that cannot decode the contents of the encapsulation, with no mechanism at the protocol level to detect the problem. Lack of correct versioning has been an ongoing problem with CORBA for years and the problem has historically been dealt with by pretending that it does not exist (meaning that different CORBA versions cannot interoperate with each other in many circumstances).
IIOP has more message types than Ice. For example, IIOP has both a cancel request and a message error message. The cancel request is meant to cancel an invocation in progress but, of course, cannot do that because there is no way to abort an executing invocation in the server. At best, a cancel request allows the server to avoid marshaling the results of an invocation back to the client. However, the additional complexity introduced into the protocol is not worth the saving. (And, at any rate, neither is there a way for an application developer to send a cancel request, nor can the run time decide on its own when it would be appropriate to send one; despite that, every compliant CORBA implementation is burdened by the need to correctly respond to a useless request.)
IIOP’s message error message constitutes similar baggage: the receiver of a malformed message is obliged to respond with a message error message before closing its connection. However, the message carries no useful information and, due to the nature of TCP/IP implementations, is usually lost instead of being delivered. This means that a compliant CORBA implementation is forced to send a useless message that will not be received in most cases when, instead, it should simply close the connection.
IIOP is vulnerable to connection loss during connection establishment. In particular, when a client opens a connection to a server, the client has no way of knowing whether the server is about to shut down and will not be able to process an incoming request. This means that the client has no choice but to send a request on a newly-established connection in the hope that the request will actually be processed by the server. If the server can process the request, there is no problem. However, if the server cannot process the request because it is on its way down, the client is confronted with a broken connection and cannot re‑issue the request because that might violate at‑most-once semantics.
Indirect binding (see page 15) in IIOP relies on a locate forward reply. Briefly, endpoint resolution is transparent to clients using IIOP. If an object reference uses indirect binding, the client issues the request as usual and receives a locate forward reply containing the endpoint of the actual server. In response to that reply, the client issues the request a second time to contact the actual server. There are a number of problems with this scheme:
Ice does not have this problem because the location service is known to clients through configuration. If the location service is moved, clients can be updated by changing their configuration and there is no need to track down a potentially unlimited number of proxies that might be out of date. Moreover, there is typically no need to move the location service. Instead, it is possible to construct federated location services that work similar to the Internet Domain Name Service (DNS) and internally forward requests to the correct resolver.
• In order to get a location forward message, clients send the actual request to the location service. This is expensive if the request parameters are large because they are marshaled twice: once to the location service and once to the actual server. IIOP adds a locate request message that allows a client to explicitly resolve the location of a server. However, CORBA object references carry no indication as to whether they are bound directly or indirectly. This means that, no matter what the client does, it is wrong some of the time: if the client always uses a locate request with a directly bound reference, it ends up incurring the cost of two remote messages instead of one; if the client sends the request directly with an indirectly bound reference, it incurs the cost of marshaling the parameters twice instead of once.
IIOP uses a codeset negotiation feature that (supposedly) permits use of arbitrary character encodings for transmission of wide characters and strings, provided sender and receiver have at least one codeset in common. Unfortunately, this feature was never properly thought through and has repeatedly led to interoperability problems. (Every single version of the CORBA specification, including the latest 3.0 version, has made corrections to the way codeset negotiation is supposed to work. Whether the latest set of corrections will succeed in dealing with the problem remains to be seen. Regardless, many pages of complexity (and many lines of ORB source code) are devoted to this (mis)feature.)
The UTF‑8 encoded Unicode used by Ice avoids all these problems without losing any functionality.
IIOP provides a fragment message whose purpose is to reduce memory overhead in the server during marshaling of the results of an operation invocation. Unfortunately, the feature is quite complex (having been mis-specified and mis-implemented repeatedly in the past). The savings to be gained through fragmentation are quite limited, yet every client-side ORB implementation is forced to provide support for the feature. (In other words, the cure is worse than the disease.)