Pages

Tuesday, July 31, 2012

Spring - Making a self configurable project

In my projects I prefer having self configurable solutions and avoid any additional involvement for deploying an enterprise application (EAR file).  For example, if the project needs to call some web services but the host address depends of the environment where the deploying is occurring (i.e. DEV, QAT, UAT, PROD).  Or you might need specific settings in each environment like DEV where you want to have more traces and debug information.  Imagine having to configure each setting every time you deploy...  plus this is prone to errors.


So how to make the solution self configurable?

In my case I use a combination of the JAVA env variable and Spring.

Set ENV Variable

Configure the JVM which hosts your application and set the vm argument:  -Denv <name>.

For example if using Geronimo application server, I will set this in the Launch Configuration where the VM arguments are configured.

-javaagent:"$(GERONIMO_HOME)/lib/agent/transformer.jar" -Djava.ext.dirs="$(GERONIMO_HOME)/lib/ext;$(JRE_HOME)/lib/ext" -Djava.endorsed.dirs="$(GERONIMO_HOME)/lib/endorsed;$(JRE_HOME)/lib/endorsed" -Xms512m -Xmx1024m -XX:MaxPermSize=512m -Dorg.apache.geronimo.home.dir="$(GERONIMO_HOME)" -Dkaraf.home="$(GERONIMO_HOME)" -Dkaraf.base="$(GERONIMO_HOME)" -Djava.util.logging.config.file="$(GERONIMO_HOME)/etc/java.util.logging.properties" -Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=false -Denv=dev

Spring - ENV Configuration

I use Spring Framework to handle many of the dynamic characteristics of the project.  With Spring I can read the JVM env variable and do the following inside the applicationContext.xml file to achieve a self-configurable solution.

Spring - ApplicationContext.xml

This file is used by Spring to configure the application being loaded.  In the configuration I list two files:  application.properties and application.${env}.properties.  Notice the property files are bundle in the compiled JAR, so they are not easily visible nor accessible.  Plus you don't have to worry about the physical path since the files will be in the classpath.  The reason for having two files is that I can use one for all the general properties and another for environment specific settings.  Be careful that the order of the property files is important in the applicationContext.xml for how values are overridden.


    
    classpath:com/jonnazario/myapp/properties/application.properties
    classpath:com/jonnazario/myapp/properties/application.${env}.properties
    






    
    
    

For my preference I have a SystemProperties class which I load with values that are important for the application (i.e. Version, DevModeEnabled, HostName). For this I pass the property values as arguments to the constructor and if they are not defined in the property files, I still set the default values within the applicationContext.xml file.

Properties file

These are example values for the general and environment specific application properties files.  See how some properties are overridden while other are not defined at all.

Configuration - General
# -- General Properties
app.Version=2012.07.01.00
app.devModeEnabled=false

Configuration - DEV
# -- DEV Properties
app.Version=work.in.progress
app.devModeEnabled=true

Configuration - PROD
# -- PROD Properties
app.hostname=www.myapp.com


Hope this helps.

No comments:

Post a Comment