views:

328

answers:

9

At the moment my build process consists of repackaging the war file with all required java libraries under WEB-INF/lib and then copying the war file to development/demo/production server to be redeployed by tomcat.

The packaged war file's size is about 41M and it has at the moment something like 40M of external java libraries. There has to be a better way. How have you solved this issue?

My development machine is a windows box with Eclipse as my IDE and Ant as my build tool. The servers are all linux boxes with Tomcat 5.5.

Should I maybe add the jar files to the war package at server side?

A: 

Can you add the non-changing Jars to the Java Library Path on the server side, and only include the regularly changing Jars in your WAR?

JeeBee
Wouldn't really like to mess up the whole server environment with libraries of one webapp.
kosoant
A: 

you could include the external java libraries in the Tomcat/lib directory. That way they stay on the server.

Mike Pone
Just beware, this can cause issue if other apps on the same server require a different version of the same lib, or issues where a single instance of a class is shared across classloaders
matt b
It can also cause a lot of grief if the classes loaded by the system classloader try to load classes that are in the WAR using it's own classloader. It can be a very fragile setup depending on the nature of the classes involved and if they attempt to dynamically load classes at runtime.
Robin
I'm with matt and Robin on this: Wouldn't really like to mess up the whole server environment with libraries of one webapp.
kosoant
+13  A: 

I can see what you are saying, and have had the same frustration with some of our webapps, but for consistency sake, I would suggest you keep things as they are. If copying the libraries to the tomcat/lib directory you may run into issues with the system classpath vs. the webapp classpath.

By keeping things as they are you are sure you are deploying the same stuff in development/demo as you are in production. Life sucks when you are manually tweaking stuff in production, or you have some crazy error because you forgot to update XYZ.jar from version 1.6 to 1.6.1_b33 in production and now it's behaving differently than what you believe is the exact same code on demo.

When working with something vital enough to have dev/demo/production systems, I think consistency is much more of an issue than .war file size.

digitaljoel
A: 

You could just deploy as a JAR file, replicate your deployment environment locally and just copy over the files that have changed and the jar itself. The pathing is the only real issue.

Or you could look into setting up an EAR.

kgrad
+1  A: 

Tomcat has a shared/lib directory, which is the proper place for global application dependencies. However, these will be visible to all applications, which will affect dependency management and may have consequences for things like static variables. I'm not sure if you can configure anything better in Tomcat.

An alternative is to switch to a more sophisticated web container. For example, WebSphere Application Server Community Edition (a blue-washed version of Geronimo) supports per-asset libraries. Other free and commercial servers support this, too. I know WebSphere Application Server does and I'm pretty sure you can do it in Glassfish.

McDowell
Thanks for the tips on more advanced containers.
kosoant
A: 

I work with the 'exploded web application' in the development servers, and occasionally in production as well. The deployment process (based on ANT) updates the JARs in WEB-INF/lib with our packages. Only in the development server, we activate Tomcat reloading which takes care of restarting the application when something changes. You should assign some extra permanent memory to these Tomcats and have a way to restart the server, as the reloading may crash Tomcat from time to time.

I know it's a weird configuration, but I can't understand how constantly repackaging the 30MB (and growing) of our typical application could do any better. May one day the development descriptor allow for external references to libraries which the container may download and cache. ??

Excuse my poor English.

Imp
+1  A: 

@McDowell, when mentioning those J2EE servers, you should precise that they are J2EE servers(servlet container + the rest).

Like @digitaljoel, I suggest to keep things like they are. It looks like you haven't done much web application deployment yet. The issues that you'll have are not worth the price(version conflicts, deployment errors, etc.).

John Doe
A: 

What you need is a version control tool and a build process.

Use CSV,SVN,GIT or whatever fit you to keep your source under control. use a build tool to build your application : Maven,ant,...

Now, when you want to deploy your application on your server ,you just have to commit your updates on your computer,update your source on your server,build your application and deploy it from the server.

This way , the server will just have to load your modifications and it should be much faster.

+1  A: 

We use the rsync tool for this (in our case, using cygwin under windows) to copy the deployments to the servers (which run linux). We use exploded WAR/EAR files (i.e. a directory structure called MyApp.war rather than a zip file called MyApp.war), rsync will only transfer the files that have changed.

In general use, rsync will transfer our 30-40 megabyte exploded EARs in about 5 seconds.

skaffman