For a recent Java project at IBM, my team was forced to consider application maintenance from the start. The situation had an interesting set of characteristics: First, the users were mobile and needed disconnected access to the application. Second, the users were dispersed worldwide. Third, the application was expected to evolve quickly. And fourth, the department had limited support resources to help users install upgrades.
Because the users were mobile, we needed to install the application locally on the their laptops, rather than having them retrieve the latest bytecodes from a server. Because the users were worldwide and frequent updates were expected (not to mention that we had a small support infrastructure with a limited travel budget), we needed a reliable means of remotely updating the application. We wanted something more seamless than an email with an attached jar file and installation instructions, or an executable packaged with InstallShield. The solution we implemented, which solved our problem nicely, was to store the application bytecodes in the same database the users replicate for the application data. We installed on everyone's workstation one jar we termed the bootstrapper. This unchanging piece of code locates the local database, loads the application-specific bytecodes, and launches the application. When the developers add a new report or fix a bug, we recompile the bytecodes and replace them in the database on the server. The next time users replicate their local database with the one on the server, they receive the new bytecodes along with the other new application data.
What makes this dynamic approach possible is the Java ClassLoader. A ClassLoader is the part of the JVM responsible for finding classes as your application instantiates them. Thanks to the foresight of
the Java creators, you can replace the default class loader with one of your own, which loads classes in just about any way
you can imagine. Any array of bytes can be interpreted as a class that your program may instantiate at runtime. The bytes
may come from files in the local machine or from a server halfway around the world, delivered via a network connection. In
our case, we put the bytes into a Lotus Notes database. For convenience, and to minimize the amount of replicated data, we
packaged all application-specific files into a compressed zip file. The java.util.zip package lets users read and write files in the zip format.