Intro
I’m working on a Java web application deployed as a WAR via Apache Tomcat.
The application settings are stored in a properties file
deployed as a resource within the WAR. A
PropertyPlaceholderConfigurer
loads this properties file in order to configure bean instances.
Deployment Issues
Initially I used a custom deploy script executing via SSH on a successful Jenkins build. (Yes, I know I should’ve been using capistrano or fabric.) This caused an issue when I went to deploy the application using Chef.
There is an
application_java
cookbook
that makes it easy to deploy WAR-based applications. Unfortunately, the
way the properties are packaged with the WAR, I was using a hacky
work-around to create the properties using a template resource
after
the application was deployed and exploded to the webapps directory.
Using a context.xml
file
The way that it seems the application_java
cookbook wants you to
specify app settings is via a context.xml
file. A
Tomcat context
provides two methods of passing variables: context parameters
and
environment entries
. I needed to use one of these methods to pass in
the location of the properties file used to configure the application.
(The application
cookbook family encourages storing configuration in
the application’s shared
deploy directory.) I found a useful article
on StackOverflow 1, but I had to wade through several other references to
figure it out completely. Here are the steps I had to take, laid out
explicitly.
Configuring the Configuration
Here’s what I had to do:
- Create an
env-entry
for variableCONFIG_PATH
in the application’sweb.xml
. - Create an
Environment
element for variableCONFIG_PATH
in the application’scontext.xml
. This is the file that will be used to configure the application using Chef. Make sure the value begins withfile:
or you’ll get an error like “Could not open ServletContext resource” - Add
jee
namespace to mybeans.xml
2 -
Add an entry to perform a JNDI lookup in my
beans.xml
:<jee:jndi-lookup id="beanConfigPath" jndi-name="CONFIG_PATH"/>
-
In my
beans.xml
PropertyPlaceholderConfigurer
entry, reference the bean above:<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" ref="beanConfigPath" /> </bean>
Conclusion
In retrospect, it may have been easy to try to use a context parameter
instead. I also had not heard of JNDI
before I worked on this issue,
so that’s another topic I need to look into. Still in the works is
making sure I can specify the location of a logback.xml
file when I
deploy via Chef. Right now I’m looking into using the Loader
element
of the context.xml
in order to add the application’s shared
directory to the classpath.