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.