I am trying to configure a Spring configuration file with database information based on whether a certain Maven profile is active. I've seen pieces of answers to this but I'm having trouble putting it all together.
I have a Maven profile like this:
<profiles>
<profile>
<id>production</id>
<activation>
<property>
<name>environment.type</name>
<value>prod</value>
</property>
</activation>
</profile>
<profile>
<id>development</id>
<activation>
<property>
<name>environment.type</name>
<value>dev</value>
</property>
</activation>
<!-- Database properties for Spring -->
<properties>
<db.driver>oracle.jdbc.driver.OracleDriver</db.driver>
<db.type>oracle</db.type>
<db.host>192.168.0.0</db.host>
<db.port>1521</db.port>
<db.name>myDb</db.name>
<db.url>jdbc:${db.type}:thin:@${db.host}:${db.port}:${db.name}</db.url>
</properties>
And a settings.xml file like this:
<servers>
<server>
<id>development</id>
<username>jsmith</username>
<password>secret</password>
</server>
</servers>
....
<profiles>
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<environment.type>dev</environment.type>
</properties>
</profile>
</profiles>
And in servlet-context.xml:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>${db.driver}</value>
</property>
<property name="url">
<value>${db.url}</value>
</property>
<property name="username">
<value>${db.username}</value>
</property>
<property name="password">
<value>${db.password}</value>
</property>
<property name="maxActive">
<value>10</value>
</property>
<property name="maxIdle">
<value>1</value>
</property>
</bean>
My question is basically, how do I get the Maven properties into the servlet-context.xml file? Do I need a .properties file? I know a little about filtering in Maven and PropertyPlaceholderConfigurer in Spring but I don't know how to put them together -- or do they go together? Or is there a simpler way?
The main question is: how are you going to deploy your WAR file to the different environemnts?, via a RPM, a jenkins build, by hand?, also do you want the same WAR file to de deployed to all the environments?
a) you want your WAR to be deployed vi a JENKINS job (or manually through maven), just process your resources and use the profile in the build process of the jar (mvn -P production clean deploy), the maven pom should include code like this:
You should define your properties in the file your_proyect.properties (one per environment) and also define config.environment.dir for all your different profiles.
b) you want the same WAR/RPM, etc. for all your projects. Then you have to define the environemt as a property in the java startup of the application servert: -DENVIRONMENT=production and then load all the properties with a parametrized PropertyPlaceholderConfigurer as yorkw pointed out:
Also remember to put all the properties in the WAR, the pom for the WAR build should include code like this:
c) A mixed one: you can manually choose an enviroment over the one defined as a property in the server (-D), you can get this by using default properties, if not found then resort to the one for that environemt, this step is quite convoluted as it requires another set of properties, if you're interested check my post: deployment for different environments with maven and spring, i'm also interested in a better solution for c)
Do I need a .properties file?
Generally speaking, YES, you need to use .properties file, this is what we do usually, especially for handling database connection configuration in spring context file.
The purpose of .properties file is to provide the capability of configuring database connections at application runtime (for web application, usually require restarting application container/server after .properties file changes). This is usually done at application deployment/installation step in different environment (DEV/TEST/UAT/PROD).
It is not a good practice to store those database connection settings in pom.xml, as the purpose of pom.xml is for project description and only used once at application build time (e.g. mvn deploy). And for most of time, even though it is packed into the final jar/war file, we don't really care and touch it after application is built.
To use .properties file in spring context, define a propertyConfigurer bean in your applicationContext, for example:
Hope this make sense.
Using what I learned from the two answers and my research, I was able to get a development/production system, controlled by the pom, that sets the correct database values.
First, in the pom, I created two profiles.
In the servlet-context.xml, in the WEBINF directory, I put place holders:
Then I created a properties file to sit in src/main/resources
I can then start Maven with
or have a settings.xml that sets the correct profile for me: