We've got a Java server application that runs on a number of computers, all connected to the Internet, some behind firewalls. We need to remotely update the JAR files and startup scripts from a central site, with no noticeable interruption to the app itself.
The process has to be unattended and foolproof (i.e. we can't afford to break the app due to untimely internet outages).
In the past we've used a variety of external scripts and utilities to handle similar tasks, but because they have their own dependencies, the result is harder to maintain and less portable. Before making something new, I want to get some input from the community.
Has anyone found a good solution for this already? Got any ideas or suggestions?
Just to clarify: This app is a server, but not for web applications (no webapp containers or WAR files here). It's just an autonomous Java program.
I believe you can hot-deploy JAR files if you use an OSGi-based app server like SpringSource dm Server. I've never used it myself, but knowing the general quality of the Spring portfolio, I'm sure it's worth a look.
It's very hard to make the update atomic, especially if you have any database updating to do.
But, if you don't, what you can do is first make sure your application can run from a relative path. That is, you can put your app in some directory, and all of the important files are found relative to that location, so that that your actual installation location is not really important.
Next, duplicate your installation. Now, you have the "running" version and you have the "new" version.
Update the "new" version using whatever tech you like (FTP, rsync, paper tape, whatever floats your boat).
Verify your installation (checksums, quick unit tests, whatever you need -- even start it up on a test port if you like).
When you are happy with the new installation, down the original running instance, RENAME the original directory (mv application application_old), rename the NEW directory (mv application_new application), and start it back up.
Your down time is reduced to server shut down and start up time (since rename is "free").
If, by chance, you detect a critical error, you have your original version still there. Stop the new server, rename it back, restart the old. Very fast fall back.
The other nice thing is that your service infrastructure is static (like your rc scripts, cron jobs, etc.) since they point to the "application" directory, and it doesn't change.
It can also be done with soft links instead of renaming directories. either way is fine.
But the technique is simple, and near bullet proof if your application cooperates.
Now, if you have DB changes, well, that's completely different nasty issue. Ideally if you can make your DB changes "backward compatible", then hopefully the old application version can run on the new schema, but that's not always possible.