Version 3

    Having different settings for different environemnt in Java EE application is very common use case.

     

    For example username/password is typically different for local development, staging and production. Another example is JSF configuration in web.xml like javax.faces.PROJECT_STAGE parameter etc.

     

    This article shows how to configure standard Maven project maven to accomplish it.

     

    Solution

    Solution is based on Maven filtering technique.

     

    Let's show it on example where we need to have configurable JSF parameter name javax.faces.PROJECT_STAGE in web.xml

    Normally it's defined in web.xml like this:

     

    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    

     

    Having this parameter configurable these three steps are needed:

    1. Define Filtering (substitution) during building war file in pom.xml

     

    <properties>
        <!-- Default name of file for filtering -->
        <filter.name>localhost</filter.name>
    </properties>
    
    <build>
        <!-- This defines source files for filtering -->
        <filters>
            <filter>${basedir}/src/main/filters/${filter.name}.properties</filter>
        </filters>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <!-- Java EE 6 doesn't require web.xml, Maven needs to catch up! -->
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <webResources>
                        <resource>
                            <directory>${basedir}/src/main/webapp</directory>
                            <!-- Turn on filtering. If you want to filter more files you can use wildcards like **/*.xml -->
                            <filtering>true</filtering>
                            <includes>
                                <include>WEB-INF/web.xml</include>
                            </includes>
                        </resource>
                    </webResources>
                </configuration> 
            </plugin>
        </plugins>
    </build>
    
    
    <profile>
        <id>production</id>
        <properties>
            <filter.name>production</filter.name>
        </properties>
    </profile>
    
    <profile>
        <id>staging</id>
        <properties>
            <filter.name>staging</filter.name>
        </properties>
    </profile>
    
    <profile>
        <id>openshift</id>
        <properties>
            <filter.name>openshift</filter.name>
        </properties>
    </profile>
    
    

     

     

     

    This Maven configuraiton defines three things:

    1. Turn on filtering of web.xml file
    2. Define source of definition for filtering (parametrized by filter.name property)
    3. Define default name for filtering and use profiles for different profiles which represents environments like localhost, staging, production or openshift

     

    2. Add filtering (substitution) files containing values for each environment

    In step 1 we defined substitution files should be placed in /src/main/filters/ folder. So we need four different files:

    /src/main/filters/localhost.properties

    /src/main/filters/production.properties

    /src/main/filters/staging.properties

    /src/main/filters/openshift.properties

     

    Each property file are standard property files with key=value format where keys will be same but values will be different for different environments.

    Example:


    jsf.projectStage=Development
    

     

     

    3. Use filter keys in web.xml

    Now we can use those keys defined in filter files in web.xml (or any other file if it's defined in pom.xml described above).

    Example:


    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>${jsf.projectStage}</param-value>
    </context-param>
    
    

     

     

    Building application for different environment

    Now you can build your app for different environment. By default localhost configuraiton is taken. If you want to change it just activate profile like this:

     

    mvn -P production
    

     

    You can activate profile in various way but it's different topic.