Thursday, March 13, 2008

A better configuration with Spring MVC

Configuration management  involve  many aspects  on  how the application has to spread in several environments for integration pourpose, QA testing, pre-production, and final production.
Said elements  affect the configuration regarding information systems addresses as database, jndi and sockets and ldap.
Let me  talk about a java project, at a certain point it will be promoted to integration then test environment.
During these stages, problems and suggestions raise up, many enhancements are made and pushed along the delivery chain. As usual it would happen that these recycles increase sharply as the timeline is getting uncomfortably tight. Managing  these releases and synchronizing the environments with the incoming changes is a error prone and time consuming task.
Best pratices suggest continuous integration as the way to manage build artifacts and deliver the applications among different environments. An external tool as would be apache continuum and maven that can deploy, setup, start the application in a completely automatic way, freeing the developers to directly handle this task.
These tools start to work from the source repository which is the ultimate source traceability hub and may say the last word about the state of the project as regarding setups and branches.

Our starting  point is always the central repository, so how to track the setup configuration for different places where the webapp will be deployed?

Suppose we are working on a Spring enabled web application, and you may take advantages  from the dynamic setting up of configuration files  path with the PropertyPlaceholderConfigurer which handle ${system-property} tags and they are filled by the Spring MVC layer.
You may create several sub folder for each config environment, for instance :

WEB-INF/local/applicationContext.xml
WEB-INF/local/log4j.properties
WEB-INF/test/applicationContext.xml
WEB-INF/test/log4j.properties

Now the application context setup is easy,  it simply tells Spring how to find the proper configuration files as the example:
<servlet>
<servlet-name>dispatch</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
   <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/${environment}/applicationContext.xml</param-value>
  </init-param>
<load-on-startup>1</load-on-startup>
</servlet>
You may also specify in the same way the log4j enviroment-specific configuration:

<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/${environment}/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
Afterwards, setup the system variable in your web container adding the "-Denvironment=[local,test]" in the JVM parameter.

2 comments:

Zeljko said...

One problem with this approach is duplication of spring xml files with all negative implications that arise from that.
Just think of how easy one forgets to "copy" new spring-beans into the other environments.

I personaly like to have environment specific "root" context that overwrite certain beans.

Anonymous said...

Or maybe you can define a separate file for an environment in the same directory as so :

< param-value>
WEB-INF/applicationContext-${environment}.xml
< /param-value>

I have not yet tried it, but just a thought.