Re: Possible Bugs - extended & one more bug

Erez Hadad <[email protected]> Mon, 26 Sep 2005 20:51:28 +0300
Newsgroups gmane.comp.corba.orbacus
Message-ID <[email protected]>
Hi Dion,

You were right in your analysis of my specific usage, only I didn't use a 
value type :)

I should start with an apology: after further enquiry into the standard, it 
seems that vendors are not required, but are rather permitted, to enforce 
java.io conformance to the CORBA.portable streams. Thus, some of my 
corrections (e.g. available()) are not entirely required. Furthermore, the 
implementation of write(int) in Sun's own J2SE ORB (1.4.2) is semantically 
different from java.io.OutputStream.write(int) - it is meant to write array 
length fields and thus write the entire integer - not just the 
least-significant byte. In that sense, it justifies your original 
implementation and makes my "correction" of write(int) a mistake. I'm sorry 
for misleading you, even though my intentions are honest.

As for my specific problem:
I'm working on a mechanism that relays CORBA requests, and I need it to be as 
fast as possible, without breaking CORBA compliance. Thus, I decided to 
experiment with custom marshalling. What I did is define a "request 
container" class that contains all the dynamic request data elements (they 
are all CORBA-marshallable). At the sender, I take DSI information and store 
it into the request container. Then I marshal the RC and convert it to a byte 
buffer to be sent as payload inside a proprietary protocol I'm using. On the 
receiver side, I un-marshal the RC again and use its data through DII to 
actually invoke the request.
At first, I used an IDL struct to store the RC class's data, then write it 
into an Any using the helper class and then marshal the Any into a 
byte-buffer using a Codec.  The reverse process was used at the receiver. 
However, this seems quite inefficient, especially in a multi-threaded 
environment (as is my case): each RC requires instantiating a new struct, a 
new Any (for containing the marshalled struct) and a new Codec (since the 
standard does not define whether a Codec can be used safely by multiple 
threads simultaneously and if it imposes thread-contention costs). 
Furthermore, the process itself seems unnecessarily costly: writing into an 
Any is actually marshalling the data and processing it for TypeCode (which I 
don't need since I'm working with a fixed type) then scanning it again to 
convert with a Codec to get the buffer which I put into my transport. A total 
of at least 3 passes over the data beyond the actual marshalling. Out of 
these 3 passes, at least 2 are redundant in my case: I assume all endpoints 
use the same CDR so the Codec is not required, and I don't need the TypeCode 
since I'm using a fixed type. So, I decided to use the 
portable.OutputStream/InputStream directly, only I needed a portable way of 
converting the contents of the portable stream into a byte sequence. Thus, I 
came to our current issue: I write the contents of an RC directly to a 
portable.OutputStream, convert it to a portable.InputStream and read it as a 
byte stream. The reverse process is used to retrieve an RC out of a byte 
stream. Too bad CORBA/Java does not allow to constuct a portable stream over 
a standard Java Input/Output stream - I could have saved another pass.
Last, to avoid portability problems arising from the mistakes I started with, 
I'm using read_octet and write_octet to process the portable streams as byte 
streams.
As for value types, I see no speed or portability advantage in using their 
specific marshalling.

Please enlighten me with any further thoughts or insights you might have of my 
problem.

Sincerely,
Erez Hadad



On Monday 26 September 2005 17:49, Dion Picco wrote:
> Hi Erez,
>
> On Sun, Sep 25, 2005 at 10:57:39PM +0300, Erez Hadad wrote:
> > Hi,
> >
> > (Using JOB-4.1.3/JDK1.4.2/Linux)
> > I believe you have bugs in com.ooc.CORBA.InputStream: according to the
> > CORBA/Java specification, the org.omg.CORBA.portable.InputStream (which
> > you implement through com.ooc.CORBA.InputStream) should extend
> > java.io.InputStream and conform to its specification. However, I have
> > noticed the following two exceptions:
> > 1. available() is not overridden, so it returns 0 even though there is
> > data to be read from the stream.
> > A possible fix:
> > public int available()
> > throws IOException {
> >   int avail = buf_.len_ - buf_.pos_;
> >   return (avail >= 0 ? avail : 0);
> > }
> > 2. read() returns the byte value of the stream's internal buffer
> > (buf_.data_[pos++]), which is a byte value [-128, +127] rather than
> > convert it to an int value in the range of [0, 255] as the Java
> > specification requires. -1 should be returned only for an end-of-stream.
> > Consequently, trying to read the stream as a Java byte-stream would fail
> > prematurely. A possible fix:
> > replace
> > return buf_.data_[buf_.pos_++];
> > with
> > return (0xff & buf_.data_[buf_.pos_++]);
> > 3. The class com.ooc.CORBA.OutputStream contains a matching bug: the
> > write() method does not conform to the java.io.OutputStream.write()
> > specification. It is implemented as write_long() where it should only
> > write a single byte - the least significant byte.
> > A possible fix:
> > replace
> > write_long(b);
> > with
> > write_octet((byte)b);
> >
> > Please verify the bugs & fixes.
> >
> > Regards,
> > Erez Hadad
>
> Yes, you are right on all three counts.  These issues conflict with the
> interface defined in the java.io package.  The reason they don't
> manifest themselves as bugs within Orbacus is that we simply don't use
> them for marshaling/unmarshaling our messages.  I will rectify this for
> the next release of Orbacus (4.3.1).
>
> I am curious as to why you have a need for these methods as well (simply
> as a way to understand the needs and uses of our customers).
> Normally our users are shielded from these classes as the jidl compiler
> will generate the code that will handle the usage of the Input/Output
> streams.  The only common case of a user dealing with such issues might
> arise during the custom marshaling of a valuetype but this would occur
> through the DataInputStream/DataOutputStream classes as well.
>
> Thanks for the bug reports and insights.
> Cheers.
_______________________________________________
OB-Users Mailing List - [email protected]
http://mail.ooc.nf.ca/mailman/listinfo/ob-users
Visit our support FAQ before you send a message.
http://www.orbacus.com/faq/support.html