Develop an environment-aware Maven build process

Extend Maven builds to port Java apps to multiple environments

1 2 3 4 5 Page 3
Page 3 of 5

Figure 4 shows Web Service Client's Maven project directory structure as viewed in Eclipse Indigo.

Figure 4. Web Service Client's directory structure

Note

As the pom.xml files for the Database and Web Service Client Maven projects show, the property files are automatically included in the JARs when they are built, as is usual for Maven projects. There are two ramifications to this automatic inclusion:

  1. The JARs themselves become environmentally specific.
  2. It is difficult to quickly see and modify the property values once the application has been deployed.

Neither of these outcomes is desirable. In fact, a process that did not include the property files bundled into the JARs would be more practical. We'll deal with that a bit later in the article.

App Config

Now that we have the pom.xmls and the project directory structure for each project laid out we can begin to extend our Maven build to be environment-aware. Our first task is to create a new Maven project that contains all of the property files in a templatized format. The App Config project's pom.xml is shown in Listing 4.

Listing 4. App-Config pom.xml

<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.foo</groupId>
    <artifactId>app-config</artifactId>
    <packaging>jar</packaging>
    <name>app-config</name>
    <version>1.0-SNAPSHOT</version>
    <description>Contains config files</description>
</project>

Figure 5 shows App-Config's Maven project directory structure as viewed in Eclipse Indigo.

Figure 5. App-Config Maven project directory structure

Notice that the directory structure for this project contains not only the templatized property files for both the Database project and the Web Service Client project, but also a property file called dev.properties. Listings 5 through 7 display the contents of all three of these property files.

Listing 5. Property file: database.properties

database.name=${database.name}
database.connection.url=${database.connection.url}
database.connection.username=${database.connection.username}
database.connection.password=${database.connection.password}
database.connection.driver.class=${database.connection.driver.class}



Listing 6. Property file: web-service-client.properties

web.service.server.wsdl.url=${web.service.server.wsdl.url}

Listing 7. Property file: dev.properties

###### WEB SERVICE SERVER ###############
web.service.server.hostname=dev-web-server.foo.com
web.service.server.wsdl.url=http://${web.service.server.hostname}/foo.svc?wsdl

###### SQL SERVER 2008 #################
database.name=foodb
database.connection.url=jdbc:jtds:sqlserver://dev-sql-server-db.foo.com:1433
database.connection.username=test
database.connection.password=password123!
database.connection.driver.class=net.sourceforge.jtds.jdbc.Driver

With the App-Config Maven project set up, we can begin on the next phase of our solution, building Parent-Pom.

Parent-Pom

Parent-POM is a new parent Maven project that utilizes App-Config. It will provide each Maven project that inherits the Parent-POM with its own set of property files, but configured for a particular environment: development, testing, or production. Like other Maven projects, Parent-POM contains a pom.xml; however, unlike the other Maven projects, the packaging type is not JAR but POM. Below is Parent-POM’s pom.xml.

Listing 8. Parent-POM’s pom.xml

<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.foo</groupId>
    <artifactId>parent-pom</artifactId>
    <packaging>pom</packaging>
    <name>parent-pom</name>
    <version>1.0-SNAPSHOT</version>
    <description>Contains the parent pom configurations</description>

    <properties>
        <environment.name>dev</environment.name>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <id>unpack-app-config</id>
                        <phase>clean</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.foo</groupId>
                                    <artifactId>app-config</artifactId>
                                    <version>1.0-SNAPSHOT</version>
                                    <type>jar</type>
                                    <overWrite>true</overwrite>
                                    <outputDirectory>${project.build.directory}/alternate-resources</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <!--This plugin's configuration is used to store Eclipse m2e settings 
                    only. It has no influence on the Maven build itself. -->
                <plugin>
                    <groupId>org.eclipse.m2e</groupId>
                    <artifactId>lifecycle-mapping</artifactId>
                    <version>1.0.0</version>
                    <configuration>
                    <!-- Content not displayed in this article for brevity purposes. -->
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
        <filters>
            <filter>${project.build.directory}/alternate-resources/configs/${environment.name}/${environment.name}.properties
        </filter>
        </filters>
    </build>
</project>

The pom.xml in Listing 8 utilizes the maven-dependency-plugin to pull from the Maven repository the App-Config project’s JAR, extract the contents of the JAR, and place them in ${project.build.directory}/alternate-resources.

Note that the path itself utilizes an implicit Maven property key, project.build.directory, which has a value of whatever project references the Parent-POM project. At the very bottom of the pom.xml, the <filter> element automatically loads all of the property keys and values in the dev.properties property file, and makes those values available during the property-filtering process of the maven-resources-plugin.

1 2 3 4 5 Page 3
Page 3 of 5