views:

205

answers:

2

Google uses bsdiff and Courgette for patching binary files like the Chrome distribution. Do any similar tools exist for patching jar files?

I am updating jar files remotely over a bandwidth-limited connection and would like to minimize the amount of data sent. I do have some control over the client machine to some extent (i.e. I can run scripts locally) and I am guaranteed that the target application will not be running at the time.

I know that I can patch java applications by putting updated class files in the classpath, but I would prefer a cleaner method for doing updates. It would be good if I could start with the target jar file, apply a binary patch, and then wind up with an updated jar file that is identical (bitwise) to the new jar (from which the patch was created).

+1  A: 

Try the javaxdelta project on Sourceforge. It should allow to create patches and to apply them.

[EDIT] This tool doesn't exist, yet. Open the JAR file with the usual tools and then use javaxdelta to create one patch per entry in the JAR. ZIP them up and copy them onto the server.

On the other side, you need to install a small executable JAR which takes the patch and the JAR file as arguments and applies the patch. You will have to write this one, too, but that shouldn't take much more than a few hours.

Aaron Digulla
Hi Aaron - I'm not looking for a binary patch algorithm implemented in java, I'm looking for a patch tool that is tailored for working specifically with JAR files, along the lines of pack200.
Ken Liu
This tool doesn't exist, yet. Open the JAR file with the usual tools and then use javaxdelta to create one patch per entry in the JAR. ZIP them up and copy them onto the server. On the other side, you need to install a small executable JAR which takes the patch and the JAR file as arguments and applies the patch. You will have to write this one, too, but that shouldn't take much more than a few hours.
Aaron Digulla
@Ken -- What Aaron is suggesting isn't a real algorithm, but is what you will want to do. Jar files are zip files with class files in them. A binary diff of old/foo.class and new/foo.class is likely to be reveal few differences, while a binary diff of old/foo.jar and new/foo.jar are likely to look way more different. You can easily just compress (zip) the binary diff of the class files and send that to your endpoints. Then at each end point they will unzip their each jar file that needs to be patched, apply the patch, and then zip them back up.
nategoose
(continued) You may not get the exact same binary jar files if you use different versions of compression tools on your endpoint than you do on you front end machine.diff and compression are very related fields, but can often not work well with each other. They are both looking for patterns of sameness and change. Essentially diffing compressed files will almost always amplify the differences. Compressing diffs, on the other hand, will likely yield so so to good compression percentage, but be much smaller than the diff of the compressed files even if that also compressed.
nategoose
guys, I get what you are saying, I really do. I'm not talking about binary diffing jar files. Did you read up on Courgette and pack200? Courgette uses an algorithm that works better than bsdiff because it specifically targets executable binaries. What I am imagining is an algorithm that exploits characteristics implicit to class files in order to produce a binary diff that is smaller than what a typical binary diff produces. Pack200 does this for compression by rearranging the contents of the class files contained in a jar.
Ken Liu
+1  A: 

.jar files are already compressed, so what you're really asking for is a compression that works well on zip files ;). If you get at it before you stuff it in the jar you have better odds of taking advantage of the knowledge that it is "java" I expect. I suspect you could adapt the factorization described in this paper as a java specific compression method.

Logan Capaldo
pack200 already deals with the compression problem; what I'm looking for is something that deals with patching.http://java.sun.com/j2se/1.5.0/docs/guide/deployment/deployment-guide/pack200.html
Ken Liu