During development I frequently have to deploy a large war-file (~45 MB) to a remote test server, normally I copy the file with scp to the server.
The WEB-INF/lib folder makes up the largest part of the war file, which includes all the required libraries (spring, apache-cxf, hibernate,...).
Now I'm searching for an fast and easy a way to redeploy only my altered files.
And how can I determine which packages are really needed by the webapp, because spring and apache-cxf comes with a lot of libs, I'm sure I don't need all of them.
I use
rsync
to copy my.war
from my local machine to production. It usually provides a big speed up, around 8-10 times.Another option is to use
git
to store the.war
files. When yougit push
a new.war
, only the differences are transferred. Also a big speed up. Some people say that git is not designed to store big files, it gets slow and does not work very well. In fact yes, the repo will grow a lot, but in some cases it could be a good option.Some numbers: My
.war
is about 50MB and when I deploy a new version, it only copies about ~4MB instead of uploading a complete new war. Both withgit
andrsync
.UPDATE: The problem I ran into it's the git repo cannot be cloned after it has several
.war
versions because it will take forever to create all the deltas and transmit them to the client.I changed the strategy by uploading the
.war
files into dropbox. Dropbox also uses kind ofrsync
and only copies deltas. From the server I wget the.war
and re-reploy the app. Hope this helps.I don't think there's a faster way to redeploy only the changes to a WAR file.
If you deploy in exploded fashion you can see what file timestamps have changed and act accordingly, but you'll have to write code to do it.
I don't know if OSGi can be a help here. That would allow you to partition your problem into modules that are more independent and swap-able.
Just curious:
When you deploy a
.war
, the first thing Tomcat does is to unpack that file into itswebapps
directory, in a subdirectory with the same name as your.war
.During development, you obviously have access to your
.class
files, the.jar
files, configuration files and whatever else eventually goes into your.war
. You can easily establish a small subset of files affected by your changes. Figure that out, and then use a script or anant
task or whatever to copy just that small handful of files straight into thewebapps/yourapp
directory on the server.To see your changes take effect, you'll need to re-start your application. If Tomcat is in development mode, one easy way to force a reload (and restart, of course) is to update
WEB-INF/web.xml
. So have your deployment processtouch
that file or otherwise update it in a way that will give it a new timestamp,scp
that over too (preferrably as the last of the files you update) and you should have a quick and easy reload.What I do is exclude WEB-INF/lib/*.jar files from the WAR and reassemble on the server side. In my case, this trims a 60MB WAR down to 250k which allows for really fast deployment.
The
<exclude name="**/lib/*.jar"/>
command is what excludes the jar's (see last code snippet for ANT build)On the server side, it's quite easy to assemble a fully populated WAR from the trimmed WAR:
For example:
Maybe not the most elegant solution, but it saves time on frequent deployment of large WAR's. I'd like to be able to do this with Maven so if anyone has suggestions, please let me know.
ANT build.xml:
Improving on Rori Stumpf answer, here is a Gradle task for the 'thinning'
This will generate v1-thin.war (weighting less then 1mb), and a libs zip.
deploy the thin war to the server (and reconstruct the libs there), and deploy the libs zip whenever you modified the versions/add libraries.