Difference between revisions of "CompressionAndRMI"

From Protege Wiki
Jump to: navigation, search
(New page: I am writing this page in case there are others who try to implement compression over rmi and find that it is more difficult than expected. Perhaps a google search will take you here and...)
 
Line 1: Line 1:
 +
I am writing this page in case there are others who try to implement compression over rmi and find that it is more difficult than expected.  There are several other pages that describe  [http://java.sun.com/javase/6/docs/technotes/guides/rmi/socketfactory/index.html how to create and use an rmisocket factory].  The tricky part is to develop the compressing input and output streams that can be used by  a socket with rmi.  The main difficulties are
 +
# the client hangs when trying to communicate with the server. This is what happens  if you simply try to use a [http://java.sun.com/j2se/1.5.0/docs/api/java/util/zip/GZIPInputStream.html GZIPInputStream]  and a [[http://java.sun.com/j2se/1.5.0/docs/api/java/util/zip/GZIPInputStream.html GZIPOutputStream].  The flush operation on the GZIPOutputStream is not sufficient to have the desired effect on the client.  RMI expects that when  it flushes the output stream on the server that all the data flushed will appear  on the client.  Instead in this case the client is still waiting for the rest of the data.  I believe that  the issue is that the GZIPOutputStream is in the middle of a compress operation and is not ready to flush everything down the wire.
 +
# A common solution to the above is to modify the GZIPOutputStream so that on a flush() operation it invokes finish().  This is indeed useful for flushing out all the data.  Unfortunately what I found is that when rmi later writes to this same stream again after the flush, an exception is thrown because one is not supposed to finish a GZIPOutputStream and then continue writing.
  
I am writing this page in case there are others who try to implement compression over rmi and find that it is more difficult than expectedPerhaps a google search will take you here and maybe this page will be useful.
+
So what I needed was a way to tell the compressing stream that I had a unit that could be compressed in its entirety without interfering with future writesMy solution was to make a compressing output stream out of a [http://java.sun.com/j2se/1.5.0/docs/api/java/util/zip/ZipOutputStream.html ZipOutputStream] out of a
  
There are several other pages that tell you how to set up a compressing socket but I had problems making these implementations work.  In particular, it is very easy to customize the socket factory used by rmi.  This can be done on a per remote object level by using the appropriate constructor for the server side implementation of the remote objects.  This is the approach that we took:
+
There are several other pages that tell you how to set up a compressing socket but I had problems making these implementations work.   
<code><pre>
 
public class ServerFrameStore extends UnicastRemoteObject implements RemoteServerFrameStore {
 
 
 
  ...
 
 
 
    public ServerFrameStore(KnowledgeBase kb) throws RemoteException {
 
        super(SSLFactory.getServerPort(SSLFactory.Context.ALWAYS),
 
              new RmiSocketFactory(SSLFactory.Context.ALWAYS),
 
              new RmiSocketFactory(SSLFactory.Context.ALWAYS));
 
</pre></code>
 
The constructor
 
<code><pre>
 
        super(SSLFactory.getServerPort(SSLFactory.Context.ALWAYS),
 
              new RmiSocketFactory(SSLFactory.Context.ALWAYS),
 
              new RmiSocketFactory(SSLFactory.Context.ALWAYS));
 
</pre></code>
 
specifies the port over which the rmi connection is made and the client and server rmi socket factories.  One can also set the rmi socket factory for all remote objects with a single set rmi socket factory call.  All of this is standard and is describe in more detail elsewhere.
 
  
 
Now some of the other pages describe how to then construct a rmi socket factory that will compress and decompress data going over  the wire.  The critical step in this work is the construction of a compressing input and output stream that will compress the data over the wire.
 
Now some of the other pages describe how to then construct a rmi socket factory that will compress and decompress data going over  the wire.  The critical step in this work is the construction of a compressing input and output stream that will compress the data over the wire.

Revision as of 17:38, November 27, 2008

I am writing this page in case there are others who try to implement compression over rmi and find that it is more difficult than expected. There are several other pages that describe how to create and use an rmisocket factory. The tricky part is to develop the compressing input and output streams that can be used by a socket with rmi. The main difficulties are

  1. the client hangs when trying to communicate with the server. This is what happens if you simply try to use a GZIPInputStream and a [GZIPOutputStream. The flush operation on the GZIPOutputStream is not sufficient to have the desired effect on the client. RMI expects that when it flushes the output stream on the server that all the data flushed will appear on the client. Instead in this case the client is still waiting for the rest of the data. I believe that the issue is that the GZIPOutputStream is in the middle of a compress operation and is not ready to flush everything down the wire.
  2. A common solution to the above is to modify the GZIPOutputStream so that on a flush() operation it invokes finish(). This is indeed useful for flushing out all the data. Unfortunately what I found is that when rmi later writes to this same stream again after the flush, an exception is thrown because one is not supposed to finish a GZIPOutputStream and then continue writing.

So what I needed was a way to tell the compressing stream that I had a unit that could be compressed in its entirety without interfering with future writes. My solution was to make a compressing output stream out of a ZipOutputStream out of a

There are several other pages that tell you how to set up a compressing socket but I had problems making these implementations work.

Now some of the other pages describe how to then construct a rmi socket factory that will compress and decompress data going over the wire. The critical step in this work is the construction of a compressing input and output stream that will compress the data over the wire.