views:

364

answers:

7

We have following problem. Developers frequently need to make small changes to our web applications. When I say small, I mean things like correcting the spelling on a web page or similar. Generating and redeploying war archives can be slow and costly in such scenarios.

How could we automate and install changes incrementally? For example, generate new exploded war, compare files with exploded war in production and then replace in production only the files affected by change: .jsp .html .class etc.

This need not be hot deployment, it’s ok to restart the server. What I wish to avoid is having to copy and deploy wars that can be 80Mb in size. Sometimes connections are slow and making such minuscule change to web application as simple spelling correction can take hours.

We use Maven to automate our build process. The key issue is to automate the whole process, so that I can be sure that app v2.2.3 in my Subversion is exactly what I have in production after incremental deployment.

A: 

You can have the master war deployed somewhere the running servers can access it, and instead of deploying war files to the individual servers you can use rsync and perl to determine if there are changes to any files in the master war, distribute them to the servers and execute restarts.

Jherico
+1  A: 

Hard to say. You can ofcourse replace single class files in an exploded webapp, but this is generally a bad idea and you don't see many people doing this.

The reason is that when you make small changes it becomes harder and harder to detect differences between production and development. The chances of you sending a wrong classfile and breaking the production server increases over time.

When you say text changes, isn't it an idea to keep the text resources seperate from the war file? That way, not only developers but maybe even the customer can easily add/change translations.

To the customer it's important, but technically it's silly to do a 80MB deploy over a slow line to fix a small typo.

You can also try to look at your build/delivery cycle and increase testing efforts to prevent these small changes.

Hope this helps.

Rolf
@Rolf: "The reason is that when you make small changes it becomes harder and harder to detect differences between production and development. The chances of you sending a wrong classfile and breaking the production server increases over time." I'd think that there are tools that can compare two files with great certainty, even not textual ones?
Dan
Yes there are tools to do that, and some are described in some answers. From my experience, sending classfiles to update a production war is ALWAYS a bad idea. Not having the problem is always better than having tools to manage the problem.
Rolf
A: 

At the moment I installed SVN on the remote server so in case of a simple udate you can just update single file. Transfering the big WAR file would be quite impractical.

You can automate to a single click deployment using putty / plink [if you are using windows] by creating a simple script on the local machine an another one in the remote machine.

At the moment I have a DEVELOPMENT SVN and a LIVE SVN. The ANT build is merging the DEV to LIVE and the commit again back to the LIVE repository. At that stage the remote server can do a SVN UP and you will get automatically the file requested.

You can furter improve the update script to restart the server in case some classes are changed and do not restart in case of updating scripts/JSP.

In this way you will have also the option to rollback to a previous version to be sure that you have a working web app all the times.

To improve the process of merging SVN this tool is quite useful. : http://www.orcaware.com/svn/wiki/Svnmerge.py

dawez
A: 

We used to do this sort of thing all of the time. We worked in a bank, and there were sometimes changes to legal phrases or terms and conditions that needed to be changed today (or more usually yesterday).

We did two things to help us deploy quickly. We had a good change control and build process. We could change and deploy any version we liked. We also had a good test suite, with which we could test changes easily.

The second was more controversial. All of our html was deployed as separate files on the server. There was no WAR. Therefore, when the circumstances came up that we needed to change something textual quickly, we could do it. If java needed changing, we always did a FULL build and deploy.

This is not something I'd recommend, but it was good for our situation.

The point of a WAR is so that everything gets deployed at the same time. If you're using a WAR, that means you want it to be deployed all at once.

One suggestion is not to do such corrections so often (once a week?). Then you don't have so much pain.

MatthieuF
@MatthieuF: "All of our html was deployed as separate files on the server. There was no WAR." Do you think you can be a bit more specific? What do you mean there was no WAR? We are still talking about standard java web applications running on Tomcat etc?
Dan
It was a standard application (under Weblogic in fact), but instead of deploying a single WAR file, we dezipped all of the files and placed them in the correct directories ourselves (we kept the JARs as JARs of course). The server was not running at deployment time, so there would be no inconsistencies.
MatthieuF
A: 

The usual answer is to use a Continuous Integration sstem which watches your subversion and build the artifacts and deploy them - you just want your web application to be abel to work even after being redeployed. Question is if that is fast enough for you?

Thorbjørn Ravn Andersen
A: 

I don't think there's a straightforward answer to this one. T

The key here is modularisation - a problem which I don't think is solved very well with Java applications at present. You may want to look at OSGi or dynamic modules lathough I'm not sure how effective they are in terms of this problem.

I've seen solutions where people drop classes into application server/servlet container, I don't agree with it, but it does appear to work... I'm sure there are horror stories though!

Maven certainly makes things easier by splitting applications into modules, but if you do this and deploy modules independently you need to make sure that the various versions play nice together in a test environment to begin with...

An alternative is to partition your application in terms of functionality and host separate functions on various servers, e.g:

  • Customer Accounts - Server A
  • Search - Server B
  • Online Booking - Server C
  • Payment Services - Server D

The partitioning makes it easier to deploy applications, but again you have to make sure that your modules play nicely together first. Hope that helps.

Jon