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#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...