I have some Domain Objects which have one or more properties that relate to binary content. These Domain Objects are sent over RMI to a server that can persist and retrieve then.
As the binary content in each case could be considerably large, I'd obviously want it to be streamed as part of the Domain Object's serialized properties when it goes over the wire, in whichever direction.
Streams obviously aren't serializable in Java, so I've looked into creating RemoteStream wrappers for InputStream and OutputStream, but these basically rely on a remote call being made for each block of data being read, adding overhead.
I'd also like to avoid sending the data over a different protocol (FTP, HTTP, whatever) if I can, as that introduces a bunch of other issues.
So what I'm wondering is what people usually do with binary data over RMI, and EJB or Jini come to that. Surely this is a common problem?
I have run into a simillar problem. Because currently there are no distribution requirements for the application the stream approach works because I have a collocated webserver and ejb server. When changing to a more distributed architecture I plan to pass arround some URL pointing to the binary content location. The URL is a lightwieght object and only when needed a stream to thebinary conetnt will be open. Of course this involves that the location is remotely accessible to all the EJB/RMI servers and the appropriate security settings. When the location is not directly accesible to the EJB/RMI servers you have to copy the binary content into an accessible intermadiate location and be carefull to delete the binary content when is no longer needed. This adds complexity but it happens to be reasonable in the case of a user uploading a file through a browser; the binary content is saved in a temp folder of the web server.
Best regards, Mircea
Thanks for your reply Mircea.
I'm still interested in hearing if anybody out there's got a solution that works via RMI though, rather than HTTP or direct socket communication.
Custom serailization can be used for large binaries. In that, before sending across the wire compress the java object using available java algoritham.
Thinking about this, you might just be right. I'm not so interested in compression, as most binaries we're passing will be images, so they're already compressed.
But yeah, assuming that the streaming of a serialised object starts before the full object graph is necessarily traversed (i.e. it doesn't flatten the whole object in memory before streaming starts), the object's writeObject() method could be implemented such that it just makes repeated calls to ObjectOutputStream.write(byte).
On the client-side you'd have to write the number of bytes you're going to send before writing the bytes, and on the server-side you'd have to read the number of bytes and only read off that number of bytes. The server-side would also have to stream each byte read into a temporary file, so it can be picked up by the persistence layer and then streamed into the database. Or alternatively, if you didn't have, say, a DAO layer, you could stream it directly into the database.