[jboss-user] [Remoting] - JBoss Remoting and compression

doychin do-not-reply at jboss.com
Mon Dec 29 03:24:12 EST 2008


I've spent some time digging into compression and I managed to make it work with JBoss 4.2.3 and Remoting 2.2.2SP8.

The problem I found was with an error previously described in another post.
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=134557

The problem comes from some extra bytes put in the output stream from compression and not read from decompression.

These extra bytes still there after unmarshalling is completed. Next time when unmarshaller reads version from the input stream it reads these extra bytes and generates the error for incorrect version.

In most recent versions I see that BufferedInputStream is used to workaround this problem but I'm not sure this will work always.

There is always a small chance that the serialized compressed data that contains these extra bytes is just a few bytes longer then the size of the buffer in the buffered input stream. So after unmarshalling is complete they will still in the socket input stream and lead again to same version error. Of course the use of BufferedInputStream reduces the chance for this error but it is still exists.

What I did to make sure it will never happen was to put the size of of the compressed data before it in the output stream and during the unmarshaling to read that size and then read the specified amount of bytes from the input stream.

Also another problem I found with current solution is that it leaks lots of memory when it is used to transfer big amounts of data for short period of time. The reason is that GZip streams depend on some native code routines in JVM and to release the resources used by these routines streams depend on the garbage collector to call their finalize methods.

Another way to release that method is to call close method on the GZip output stream but this will also close the underlying stream(in this case it is the buffered stream which will close the socket output stream).

In order to avoid that I used instead ByteArrayOutputStream on the marshaling side and ByteArrayInputStream on the unmarshaling side to store the compressed data to byte array and then to write that byte array to the socket output stream/read from input stream to byte array and then pass that byte array to GZip input stream.

Now when I have separated the socket streams from GZip streams I can call close on these in order to release the memory used during the compress/decompress process.

I hope these comments will help other people to avoid the same problems I faced already.

Doychin Bondzhev

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4198688#4198688

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4198688



More information about the jboss-user mailing list