WAR files : to explode or not?
What's your preference?
In Stop the pollution in WEB-INF/classes, Sebastiano talks about the proliferation of configuration files underneath the /WEB-INF/classes directory of Java EE web applications. It's an interesting post and I like the recommendation of placing configuration files in a separate directory. However, it was the first comment that sparked me to write this blog entry.
WAR files are used a lot, in my experience, far more than exploded directories.
Personally, I'm starting to use WAR files for deployment much less than I ever used to, and this is exactly because of the reasons outlined in Sebastiano's blog entry. Now, I prefer to keep the exploded web application directory structure outside of the web container installation and simply link to it instead (e.g. using a separate Tomcat context definition). Problems with throwing a single deployable unit at a web container installation include...
- Configuration can't be tweaked if needed (e.g. log levels).
- Application patches are harder to apply.
- Web container upgrades are more complex.
There's also something more fundamental. Back in the good old days of J2EE, it was quite common to see configuration defined at the application/web server level, utilising JNDI for example. Now, frameworks are pushing configuration back into the web application because it does make for applications that are easier to port between containers. You just have to take a look at Spring and Acegi for examples of how database and security configuration can now reside alongside the webapp, in a container independent way.
This has some interesting consequences, particularly if you need to hand-off a web application to a separate team for deployment into production. Typically, development doesn't have access to the production configuration (e.g. database credentials) so providing an exploded webapp tends to make installation/deployment/customisation an easier process, regardless of whether it's manual or automated.
I'm curious, what's your preference - a WAR file or its exploded form?
Re: WAR files : to explode or not?
Each war file is completely self-contained, and can run by simply dropping it into a container - however, the first thing it does when initialising is to look for a place to put any user-modifiable files. This "looking" process may be something such as a JNDI lookup, or a default web page asking for a directory, a hard-coded external location, or whatever - the details depend on the application and its intended use.
Once the app has found its place, it first checks to see if a set of configs are already there (in which case it uses them), if there are no pre-existing configs, the application extracts a default set to the discovered place and uses them.
For me this gives the benefits of both approaches, the application will run with zero configuration and any "user servicable parts" can easily (and persistently) be modified as needed.
Thoughts,
Re: WAR files : to explode or not?
Re: WAR files : to explode or not?
Re: WAR files : to explode or not?
Re: WAR files : to explode or not?
As for deployer who needs to edit some file inside a WAR/EAR, I've written a Ruby script that allows one to do that without having to extract and repackage everything.
Re: WAR files : to explode or not?
Spring's JndiObjectFactoryBean works very well here including support for a default value.
JNDI is also used for configuration of other properties like the host names, or Hessian base URL:
<bean id="customerService" class="com.xxx.core.support.JndiConfiguredHessianProxyFactoryBean">
<property name="baseUrlJndiName" value="java:comp/env/coreRemotingUrl" />
<property name="defaultBaseUrl" value="http://localhost:8080/core/remoting" />
<property name="serviceName" value="CustomerService" />
<property name="serviceInterface" value="com.xxx.core.service.CustomerService" />
</bean>
which allows overriding the default in tomcat's server.xml (or whatever app server you use).
Simon is a hands-on software architect who works within