Archived

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

3.5.0 requests missing parameter encapsulation headers?

Greetings,

I've tried to port some unmodified working code from 3.4.1 to 3.5.0 on Win32. I have a process that uses ice_invoke_async() to call another server process. With 3.5.0 a simple operation is failing at the request server throwing Ice::UnmarshalOutOfBoundsException from BasicStream.h:235.

I've traced the problem to a missing encapsulation header for the marshaled request parameter data. Looking at the incoming buffer the HeaderData is correct and the RequestData is correct but there is no 6 octet encapsulation header between the null context value and the beginning of the parameter data.

Looking at the 3.4.1 code, at OutgoingAsync.cpp:468 in IceInternal::OutgoingAsync::__prepare() there is a call to _os.startWriteEncaps() that writes a 6 octet placeholder encapsulation header for async messages.

Looking at the 3.5.0 code, the same function in the same file is missing the _os.startWriteEncaps() presumably replaced by some other mechanism. But tracing through the code in IceProxy::Ice::Object::begin_ice_invoke() starting at Proxy.cpp:624 I don't see any replacement kicking in. The end result is a broken request where the server interprets the first 4 octets of the actual parameter data as the parameter data encapsulation length causing the out of bounds exception.

I've tried every combination of encapsulation and protocol version in the client's proxy string with no change.

I was reluctant to consider this a bug since it's so basic thinking there must be an API change, but if there has been I'm not able to find anything about it. In fact in the protocol section of the 3.5.0 Ice Manual the first Version Ground Rule is "Encapsulations always have a six-byte header".

My workaround without changing Ice code is to roll my own parameter encapsulation header and prepend it to the inParams ByteSeq to ice_invoke_async. But I'm also having to manually strip the encapsulation header out of the outParams ByteSeq of AMI_Object_ice_invoke::ice_response() before I can un-stream the reply. So it seems that something isn't right with the 3.5.0 async invokes or something has changed with how it is to be used.

Any ideas?

Regards,


David Hinson

Comments

  • mes
    mes California
    Hi David,

    Welcome to the forum.

    You're correct in that the API requirements did change between 3.4 & 3.5. Essentially, the caller is now responsible for managing the encapsulation. We mentioned this change in the release notes (see the "Changed APIs" section). The code example for synchronous blobjects also shows the new requirements.

    Take care,
    Mark
  • Thanks for the speedy solution.

    I saw mention of changes to the blobject API in the release notes but I'm not using blobjects just the streaming API for dynamic invocation so I dismissed it. For streaming API changes it mentioned new functions for object and exception demarcation but nothing about encapsulation changes.

    But I get the gist and was able to fix my code by adding startEncapsulation() and endEncapsulation() where appropriate around the streaming API calls.

    Regards,

    David Hinson

    mes wrote: »
    You're correct in that the API requirements did change between 3.4 & 3.5. Essentially, the caller is now responsible for managing the encapsulation. We mentioned this change in the release notes (see the "Changed APIs" section). The code example for synchronous blobjects also shows the new requirements.
  • mes
    mes California
    I can see how a reader that doesn't use the blobject API might skip right over that section in the release notes. I changed the text to use "dynamic invocation and dispatch" instead.

    Regards,
    Mark