views:

62

answers:

2

I am just starting to package my web application project as a WAR file and am running into differences between the configuration for Tomcat vs Jetty vs JBoss vs Websphere, etc.

Should I try to configure some super-smart an all-in-one WAR file, or should I create different Maven profiles to create different WARs for each app server?

I don't think I should create a separate Maven module for each app server WAR, should I?

+6  A: 

I would initially try to get that working with one super-smart war. I don't know what problems you run into, exactly, but jboss-web.xml and jetty-web.xml should be able to coexist in one WEB-INF.

If reality isn't so generous, I would use the war overlays feature and version classifiers. Filesystem structure and pom.xmls would be like this:

myproject                (packaging: pom, version: 1.0.0-SNAPSHOT)
+-- myproject-war        (packaging: war, version: 1.0.0-SNAPSHOT)
+-- myproject-war-jboss  (packaging: war, version: 1.0.0-jboss-SNAPSHOT)
+-- myproject-war-jetty  (packaging: war, version: 1.0.0-jetty-SNAPSHOT)

The two appserver-specific wars contain just the appserver-specific files and import the plain war as an overlay. Three different war's get deployed into your Maven repository, differing in version number only by the classifier part (e.g. myproject-war-1.0.0-jboss).

Ideally, you'd get the versioning set up in pom.xml with something like <version>${project.parent.version}-jboss</version>, but I'm not entirely sure that can be combined with the SNAPSHOT classifier and still work.

Barend
I like the overlay idea, hadn't thought of that. Is there a reason you wouldn't use Maven profiles to include/exclude certain files in the WAR?
HDave
I prefer the "one directory, one pom.xml, one `mvn` execution, one repository artifact" approach. I find it to be more predictable, less likely to run into Maven weirdness.
Barend
+1  A: 

I try never to ship configuration inside a war. The code shouldn't care what environment it's shipped into. It makes deployment more complex, but the flip side is that you can easily push out a config change and have to be concerned about accidentally deploying code changes to an environment.

This advice applies doubly in this case as it seems like you have the challenge of different environments and different containers.

Julian Simpson
So how do you help customers with installation...separate install program, instructions? Also I am interested in making deployment super easy for developers and testers.
HDave
Use cargo to make deployment super easy for developers. I believe it can copy non-war artifacts around.
Julian Simpson
I've always ended up needing to write a seperate deployment script anyhow. What has worked well in the past is making one big zipfile of deployable stuff - including app, config, db deltas, etc. Then it's easy to script deployment as you know you have all the dependencies.
Julian Simpson
@Julian - How to you get things like spring configuration to be external to the WAR file? Or does the script you refer to modify the contents of the WAR?
HDave
Sorry for the slow response, HDave. I've always used the PropertyPlaceHolderConfigurer - so you end up with configurations in the deployable, but the *values* get read from property files. You can do great things with JNDI to pass locations of files, as well. That way your app doesn't have unlawful carnal knowledge of the outside world, but still enjoys the benefits of reading files from outside the container. See http://forum.springsource.org/showthread.php?t=31598.
Julian Simpson
Thanks for the advice. I am going to create a single WAR file with no app-server or customer specific configuration in it. For purposes of integration and developer testing Cargo looks great. Will use JNDI to locate and use external Spring configuration files.
HDave