I couldn't find any pre-fabbed libraries that support resumable compression in the manner I required. There are, however, many of the bits and pieces available under open licenses to write your own. I've now got a client/server solution that satisfies all the constraints outlined in the question.
The idea is similar to the chunking ideas outlined above, but the server manages the chunking and does some bookkeeping that maps compressed chunks on the client to compressed chunks on the server. There are no temp files anywhere in the solution. The basic protocol is as follows
(1) The client sends a manifest to the server, containing the
to-be contents of the zip file
(2) The server sends back an ID for the manifest
Then repeatedly
(3) The client asks the server "is there anything still
required for the manifest with ID X"
(4) The server replies "no", or with a manifest entry
for a file in the manifest, plus a offset and length to send
(5) The client compresses that chunk and sends it (plus some
bookkeeping info)
(6) The server puts the chunk into the every growing zip file,
plus appropriate zip file crud. If the server orders
the chunks it asks the client for appropriately, this can
all be done by file appends.
The server only updates the manifest each time step 6 completes successfully, so failures during steps 3-6 (including crashes on the server or client) can be resumed safely (well, more or less).
There are a few bits that were a little fiddly in doing chunk-wise zip file creation. The basic thing that needs to be achieved is to find a chunk-able compression algorithm. Deflate can be used in this manner.
The java ZipOutputStream and DeflaterOutputStream are not really suitable for 'chunk-wise' deflation/zipping, since they don't allow an arbitrary flushing. There is a BSD-style licensed java implementation of ZLib at http://www.jcraft.com/jzlib. I haven't benchmarked it for speed, but it gives the same output as the Java implementation. JZLib is great, and is supports all the flushing modes of ZLib (unlike the java.util.zip.Deflate implementation).
Also, Zip files compute a CRC for each entry. So, the manifest entry in step 4 contains a 'partial' CRC, which for each chunk is updated and sent back in the book-keeping info in step 5. There is a public domain implementation of CRC for java at http://www.axlradius.com/freestuff/CRC32.java. I've benchmarked it and it is as fast as (and provides equivalent CRCs) the native java implementation.
Finally, the Zip file format is quite pernickety. I managed to piece together most of an implementation from the wikipedia page and http://www.pkware.com/documents/casestudies/APPNOTE.TXT. Although at one point I couldn't work the right value for one of the fields. Luckily the JDK's ZipOutputStream source is available so you can see what they do.