How to configure maven build for a single project for multiple environments

This post shows how to configure maven build for a single project that needs to be deployed to multiple  environments. In other words, when we need a common code base that can be built towards STAGING or DEVELOPMENT environment or for WILDFLY / WEBLOGIC / TOMCAT application servers.

The source code of the complete example is here

The structure of the multi-module maven example project is the following:

For this example, we want to build different releases of our modules depending on the deployment target. This is because Wildfly and Weblogic environments demand slightly different persistence.xml files. Therefore, the multiple-env-jpa module which contains the JPA Entities and the persistence.xml file, should contain the proper persistence.xml flavor, depending on the target server. For this reason, jpa module contains 2 different files with 2 configurations as shown in the figure below.

During build, we configure maven to copy -> rename a select file, either weblogic-persistence.xml or wildfly-persistence.xml as the final: persistence.xml

<parent>
    <groupId>com.intrasoft</groupId>
    <artifactId>multiple-env-demo-parent</artifactId>
    <version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>multiple-env-jpa</artifactId>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <classifier>${target.server}</classifier>
            </configuration>
        </plugin>
        <plugin>
            <groupId>com.coderplus.maven.plugins</groupId>
            <artifactId>copy-rename-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

<profiles>
    <profile>
        <id>wildfly</id>
        <properties>
            <target.server>${wildfly.suffix}</target.server>
        </properties>

        <build>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>com.coderplus.maven.plugins</groupId>
                        <artifactId>copy-rename-maven-plugin</artifactId>
                        <version>1.0.1</version>
                        <executions>
                            <execution>
                                <id>rename-file</id>
                                <phase>validate</phase>
                                <goals>
                                    <goal>copy</goal>
                                </goals>
                                <configuration>
                                    <overWrite>true</overWrite>
                                    <sourceFile>${basedir}/src/main/resources/META-INF/wildfly-persistence.xml</sourceFile>
                                    <destinationFile>${basedir}/src/main/resources/META-INF/persistence.xml</destinationFile>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </pluginManagement>
        </build>
    </profile>
    <profile>
        <id>weblogic</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <target.server>${weblogic.suffix}</target.server>
        </properties>
        <build>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>com.coderplus.maven.plugins</groupId>
                        <artifactId>copy-rename-maven-plugin</artifactId>
                        <version>1.0.1</version>
                        <executions>
                            <execution>
                                <id>rename-file</id>
                                <phase>validate</phase>
                                <goals>
                                    <goal>copy</goal>
                                </goals>
                                <configuration>
                                    <overWrite>true</overWrite>
                                    <sourceFile>${basedir}/src/main/resources/META-INF/weblogic-persistence.xml</sourceFile>
                                    <destinationFile>${basedir}/src/main/resources/META-INF/persistence.xml</destinationFile>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </pluginManagement>
        </build>
    </profile>
</profiles>

The 2 different profiles are defined in the parent pom, one for the weblogic build and one for the wildfly build, in each profile, we initialize the target.server variable accordingly:

<profiles>
    <profile>
        <id>wildfly</id>
        <properties>
            <target.server>${wildfly.suffix}</target.server>
        </properties>
    </profile>

    <profile>
        <id>weblogic</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <target.server>${weblogic.suffix}</target.server>
        </properties>
    </profile>

</profiles>

<properties>

    <revision>1.3</revision>
    <weblogic.suffix>WLOGIC</weblogic.suffix>
    <wildfly.suffix>WFLY</wildfly.suffix>

</properties>

The only thing we should do, is to fire a maven install:

mvn clean install

But the problem is that we want to differentiate the final jar, in order to distingush somehow if it was made for wildfly or for weblogic environment. We cannot change the name of the jar dynamically (of course!) and we also cannot use different versions.

Thankfully maven gives us the solution with the classifiers. We can define and configure the maven jar plugin in the jpa module:

<plugin>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <classifier>${target.server}</classifier>
    </configuration>
</plugin>

This will automatically append during package phase the classifier name at the end of the jar file:

 

 

 

 

 

 

 

In order to use a specific “flavor” (either the weblogic, or the wildfly) of the jpa packages, the clients of the jpa module must also define the necessary classifier in the dependency declaration.

This is for example, the pom.xml of the multiple-env-service module, which needs the jpa module:

<dependencies>

    <dependency>
        <groupId>com.intrasoft</groupId>
        <artifactId>multiple-env-jpa</artifactId>
        <version>${project.version}</version>
        <classifier>${target.server}</classifier>
    </dependency>

    ...

</dependencies>

So to make the service module fetch the wildfly flavor of the multiple-env-jpa library we should build it like this:

mvn clean install -P wildfly

That’s all!

 

 

The source code of the complete example is here

 

This entry was posted in Software Engineering and tagged , , , . Bookmark the permalink.