Note also that for the purpose of this article, we'll only build for the development environment, which is why the App-Config project contains a dev.properties
file but not a test.properties
file. We can pass in the environment name (such as dev
or test
) upon executing a Maven build, via the JVM argument-passing construct -Dproperty key='property value'
. Passing the environment property value in this manner overrides the property value specified in the pom.xml (the default in pom.xml is set to dev
in this example).
Database inherits Parent-POM
Our next step is to modify the Database Maven project's pom.xml so that it references the Parent-POM project. During the Maven clean phase of the Database project, the entire contents of the App-Config project JAR file will then be extracted into the Database project’s target/alternate-resources
directory. Listing 9 modifies the Database project’s pom.xml to incorporate the Parent-Pom project’s pom.xml.
Listing 9. Modifying the Database project pom.xml to inherit Parent-Pom
<parent>
<groupId>com.foo</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>database</artifactId>
<packaging>jar</packaging>
<name>database</name>
<version>${app.version}</version>
<description>Contains code to connect to MS SQL Server database.
</description>
<properties>
<app.version>1.0-SNAPSHOT</app.version>
</properties>
Note that the version of the pom.xml is now captured as a property. This allows us to dynamically set the version of the resulting JAR during the Maven build phase. We do this not by modifying the <app.version>
property value directly in the pom.xml, but by passing it in via a Java system variable, in this case –Dapp.version=1.0
. The property value is passed in exactly how we’d pass in an environment variable. In a real-world project, we would make this change to all projects, including App-Config.
Filtering and copying property files
Another addition to the Database application’s pom.xml will allow the database.properties template property file to be modified with the property values for each environment. This process occurs during the Maven clean phase. The resulting property files are placed as follows:
target/alternate-resources/configs/dev/database/database.properties
Obviously we don’t want property files placed in the resources directory because then they will be included in the JAR artifact. Storing property files in JARs is not ideal because property values must change per environment. It is, however, still useful to include these resources in a separate directory for testing purposes. The directory will then be filtered for the target environment. Listing 10 shows the Database project's pom.xml filtering for the target/conf
directory during the Maven clean phase.
Listing 10.Copying and filtering property files
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>filter-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/conf</outputDirectory>
<resources>
<resource>
<directory>target/alternate-resources/configs/${environment.name}/${project.artifactId}/</directory>
<includes>
<include>database.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Adding this plugin to the Database project's pom.xml ensures that every time the project is cleaned, the target/conf
directory will contain the database.properties file. This file is populated with all of the development property values specific to the keys used in the database.properties template file.
If you are executing this application in standalone mode, you can manually copy the database.properties file from the target/conf
directory to the src/main/resources
directory and rebuild. That will cause the property file to be included in the resulting JAR. However, if the JAR is to be included as part of another application and has environment-specific properties (as database.properties has), including the property file in the JAR is not ideal. You may be wondering, given that property files are not included in the JAR, how the Mule ESB application will provide a database.properties file to the Database application at runtime. The answer lies in the Mule application's directory structures.
The Mule ESB application
In a typical Mule ESB application, all of your classes are packaged into JARs, which go in the lib directory. Everything else that you want in the application’s classpath (including classes not contained in a JAR as well as resources such as property files) goes under the classes directory. A generic Mule project directory structure is shown in Figure 6.
The setup for our environment-aware Mule project is slightly different because in this case, all of the property files for the Database project and the Web Service Client project will be copied during the Maven clean phase into the Mule project’s resources directory. During the Maven Install phase, all of those property files will be included in the resulting Mule ZIP deployable app’s classes directory. This will ensure that they are accessible as resources via the classpath. The change to the Mule project’s pom.xml is shown in Listing 11.
Listing 11. Additions to the Mule ESB project pom.xml
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>filter-regional-resources-services</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/main/resources</outputDirectory>
<resources>
<resource>
<directory>${basedir}/target/alternate-resources/configs/${environment.name}/database</directory>
<filtering>true</filtering>
<includes>
<include>database.properties</include>
</includes>
</resource>
<resource>
<directory>${basedir}/target/alternate-resources/configs/${environment.name}/web-service-client</directory>
<filtering>true</filtering>
<includes>
<include>web-service-client.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Inspecting this change, you can see that the property files are placed in the Mule ESB project’s resources directory. The Mule Maven plugin will ensure that the property files are placed in the classes directory within the resulting ZIP file, making these property files accessible to the classpath.