One of the fundamental requirements of a build process is that it must be possible to use different configuration for binaries, which are used in different environments. If you are using Maven, it is possible to fulfill this requirement by using build profiles.
This can be done either by using maven ant-run plugin as shown here. But a more robust and maven specific way of doing is to have a separate profile for development, testing and production purposes.Each profile must have its own configuration file.
These requirements can be fulfilled by following these steps:
These steps are described with more details in following Sections.
Creating Profile Specific Configuration Files
First, I created profiles directory under the project’s resources directory. After that was done I created 3 config files for dev,prod and test environment. Here's the project structure:
Adding the Build Profile Configuration To Pom.xml
Second,add the build profile configuration to the POM file. The profile configuration section of the POM file is given (with comments highlighted) below:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>DemoWebApp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>DemoWebApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- Profiles configuration -->
<profiles>
<profile>
<id>dev</id>
<!-- Dev profile is active by default -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!--
Specifies the build profile id, which is used to find out the correct properties file.
This is not actually necessary for this example, but it can be used for other purposes.
-->
<env>dev</env>
</properties>
<build>
<filters>
<!--
Specifies path to the properties file, which contains profile specific
configuration.
-->
<filter>src/main/resources/profiles/config-${env}.properties</filter>
</filters>
<resources>
<!--
Placeholders found from files located in the configured resource directories are replaced
with values found from the profile specific configuration files.
-->
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<!--
You can also include only specific files found from the configured directory or
exclude files.
-->
<!--
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
-->
</resource>
</resources>
</build>
</profile>
<profile>
<id>test</id>
<properties>
<!--
Specifies the build profile id, which is used to find out the correct properties file.
This is not actually necessary for this example, but it can be used for other purposes.
-->
<env>test</env>
</properties>
<build>
<filters>
<!--
Specifies path to the properties file, which contains profile specific
configuration.
-->
<filter>src/main/resources/profiles/config-${env}.properties</filter>
</filters>
<resources>
<!--
Placeholders found from files located in the configured resource directories are replaced
with values found from the profile specific configuration files.
-->
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<!--
You can also include only specific files found from the configured directory or
exclude files.
-->
<!--
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
-->
</resource>
</resources>
</build>
</profile>
<profile>
<id>prod</id>
<properties>
<!--
Specifies the build profile id, which is used to find out the correct properties file.
This is not actually necessary for this example, but it can be used for other purposes.
-->
<env>prod</env>
</properties>
<build>
<filters>
<!--
Specifies path to the properties file, which contains profile specific
configuration.
-->
<filter>src/main/resources/profiles/config-${env}.properties</filter>
</filters>
<resources>
<!--
Placeholders found from files located in the configured resource directories are replaced
with values found from the profile specific configuration files.
-->
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<!--
You can also include only specific files found from the configured directory or
exclude files.
-->
<!--
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
-->
</resource>
</resources>
</build>
</profile>
</profiles>
</project>
Now we have created the needed profile specific configuration files and configured Maven to use them. As explained earlier, the configuration file contain only one property called jdbc.url, which specifies the database url . Now this value will be used in spring-bean.xml file during maven build based on profile you pass.
Note: Spring dependency are not included in the pom.The tutorial just focus on demonstrating multi environment project set up with Maven.
Here's the content of different config files:
config-dev.properties
jdbc.url=jdbc:dev
config-prod.properties
jdbc.url=jdbc:prod
config-test.properties
jdbc.url=jdbc:test
Maven Before processing (spring-bean.xml):
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc.url}"/>
</bean>
Now build your project based on your requirement for different environment (for example prod):
mvn clean package -P prod
Maven after processing (spring-bean.xml)
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:prod" />
</bean>
I hope this tutorial was informative. There does not seem to be too much information on how to do this sort of thing multiple environment build with Maven, perhaps because this process is not standard and teams and organizations have evolved different strategies to deal with this problem.
Reference:
http://maven.apache.org/guides/mini/guide-building-for-different-environments.html
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
This can be done either by using maven ant-run plugin as shown here. But a more robust and maven specific way of doing is to have a separate profile for development, testing and production purposes.Each profile must have its own configuration file.
These requirements can be fulfilled by following these steps:
- Creating profile directories and profile specific configuration files.
- Adding build profile configuration to the POM file.
These steps are described with more details in following Sections.
Creating Profile Specific Configuration Files
First, I created profiles directory under the project’s resources directory. After that was done I created 3 config files for dev,prod and test environment. Here's the project structure:
Adding the Build Profile Configuration To Pom.xml
Second,add the build profile configuration to the POM file. The profile configuration section of the POM file is given (with comments highlighted) below:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>DemoWebApp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>DemoWebApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- Profiles configuration -->
<profiles>
<profile>
<id>dev</id>
<!-- Dev profile is active by default -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!--
Specifies the build profile id, which is used to find out the correct properties file.
This is not actually necessary for this example, but it can be used for other purposes.
-->
<env>dev</env>
</properties>
<build>
<filters>
<!--
Specifies path to the properties file, which contains profile specific
configuration.
-->
<filter>src/main/resources/profiles/config-${env}.properties</filter>
</filters>
<resources>
<!--
Placeholders found from files located in the configured resource directories are replaced
with values found from the profile specific configuration files.
-->
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<!--
You can also include only specific files found from the configured directory or
exclude files.
-->
<!--
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
-->
</resource>
</resources>
</build>
</profile>
<profile>
<id>test</id>
<properties>
<!--
Specifies the build profile id, which is used to find out the correct properties file.
This is not actually necessary for this example, but it can be used for other purposes.
-->
<env>test</env>
</properties>
<build>
<filters>
<!--
Specifies path to the properties file, which contains profile specific
configuration.
-->
<filter>src/main/resources/profiles/config-${env}.properties</filter>
</filters>
<resources>
<!--
Placeholders found from files located in the configured resource directories are replaced
with values found from the profile specific configuration files.
-->
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<!--
You can also include only specific files found from the configured directory or
exclude files.
-->
<!--
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
-->
</resource>
</resources>
</build>
</profile>
<profile>
<id>prod</id>
<properties>
<!--
Specifies the build profile id, which is used to find out the correct properties file.
This is not actually necessary for this example, but it can be used for other purposes.
-->
<env>prod</env>
</properties>
<build>
<filters>
<!--
Specifies path to the properties file, which contains profile specific
configuration.
-->
<filter>src/main/resources/profiles/config-${env}.properties</filter>
</filters>
<resources>
<!--
Placeholders found from files located in the configured resource directories are replaced
with values found from the profile specific configuration files.
-->
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<!--
You can also include only specific files found from the configured directory or
exclude files.
-->
<!--
<includes>
<include></include>
</includes>
<excludes>
<exclude></exclude>
</excludes>
-->
</resource>
</resources>
</build>
</profile>
</profiles>
</project>
Now we have created the needed profile specific configuration files and configured Maven to use them. As explained earlier, the configuration file contain only one property called jdbc.url, which specifies the database url . Now this value will be used in spring-bean.xml file during maven build based on profile you pass.
Note: Spring dependency are not included in the pom.The tutorial just focus on demonstrating multi environment project set up with Maven.
Here's the content of different config files:
config-dev.properties
jdbc.url=jdbc:dev
config-prod.properties
jdbc.url=jdbc:prod
config-test.properties
jdbc.url=jdbc:test
Maven Before processing (spring-bean.xml):
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc.url}"/>
</bean>
Now build your project based on your requirement for different environment (for example prod):
mvn clean package -P prod
Maven after processing (spring-bean.xml)
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:prod" />
</bean>
I hope this tutorial was informative. There does not seem to be too much information on how to do this sort of thing multiple environment build with Maven, perhaps because this process is not standard and teams and organizations have evolved different strategies to deal with this problem.
Reference:
http://maven.apache.org/guides/mini/guide-building-for-different-environments.html
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
No comments:
Post a Comment