Wow my bran hurts after just reading this!

-dain

On Dec 13, 2006, at 1:47 PM, Rick McGuire wrote:

Ok, I finally got this problem sorted out, and it was a nasty one. The root of the problem was code in InputStream.readTypeCodeImpl(), and it was very subtle. This code was doing the following:

1. Calling read_ulong() to read the kind information for the type code. 2. Saving the current buffer position - 4 in the variable oldPos. This position is the buffer position of the start of the typecode.
  3. In the switch statement for the various type codes, read_ulong()
     was called again to retrieve an encapsulation length.
  4. An id string for the cache was read using read_string().
  5. checkCache() was called to see if this type had been encountered
     before.  If it had, then the buffer read position was placed at
"oldPos + 8 + length", skipping over the entire type code and just
     using the value from the cache.

This was failing because the type code (read in step 1) and the encapsulation length (read in step 3) are on opposite sides of a chunk boundary. When a type is reused, checkCache is positioning the buffer pointer 4 bytes short of where it needed to be, thus messing everything up. I was able to fix this by moving the pointer relative to the start of the encapsulation length, rather than the beginning of the entire type code. Based on what I've been seeing for chunk sizes, I'm reasonable confident that all of the type information from that point on will be contained in a single chunk. In any event, this test case is now finally working.

Rick

Rick McGuire wrote:
I'm working on a fairly complicated test case that involves sending and receiving a very large object across RMI. The object in question is a 3-dimensional array of Vectors. The Vectors are all 5 elements in size, each element consisting of an Integer instance. There were a number of problems I needed to fix first in array handling, but things appear to be working correctly now. The Vectors appear to be deserializing correctly. Each one contains an Object array that appears to be the correct size. The Integers are getting deserialized ok, until around the 50th or so value is read from the stream. At that point, I'm getting a MARSHAL exception for an invalid value type code. The bogus value is 0x3800. I don't know here this value came from, since the serialized object was generated by a Sun RMI server. Does this value have an special meaning to anybody? Is it possibly a chunking marker, or is something else going on here?

Rick



Reply via email to