Guide to Maven Build Profiles

Build profiles are elements available in the POM, and are triggered using variety of ways. Profiles are created for customizing build based on requirement, environment, property file, JDK, System OS and etc,. Profiles will also minimize the use of -f option of maven which allows user to create another POM with different parameters or configuration to build which makes it more maintainable since it is runnning with one POM only.

What are the different types of profile? Where is each defined?

  • Per Project– Defined in the POM itself (pom.xml).
  • Per User– Defined in the Maven-settings (%USER_HOME%/.m2/settings.xml).
  • Global– Defined in the global Maven-settings (${maven.home}/conf/settings.xml).

How can a profile be triggered?

A profile can be triggered/activated in several ways:

  • Explicitly
  • Through Maven settings
  • Based on environment variables
  • OS settings
  • Present or missing files

A Basic Example

Normally when we run mvn package,the unit tests are executed as well. But what if we want to skip unit tests to quickly package the artifact and run it to see if it works?

Let’s create a no-tests profile which sets the maven.test.skip property to true:

<profile>
    <id>no-tests</id>
    <properties>
        <maven.test.skip>true</maven.test.skip>
    </properties>
</profile>

Next, we’ll execute the profile by running the mvn package -Pno-tests command.

Now the artifact is created and the unit tests are skipped. This is just an introduction, we can make more complex setup using profiles upon deep understanding.

Profiling in POM file for Project

Let’s see how to configure Maven to solve simple configuration set-ups. By simple configuration set-up you only have a single file or a small set of files that vary for each environment. There are other better ways also to handle configuration issues.

Create a simple maven project with following standard project directory structure,

pom.xml
src/
  main/
    java/
    resources/
  test/
    java/

Under src/main/resources create three files:

  • environment.properties – This is the default configuration and will be packaged in the artifact by default.
  • environment.test.properties – This properties file will be used for test environment.
  • environment.prod.properties – This properties file will be used in the production environment.In the project descriptor, you need to configure the different profiles. Let’s take test profile as example for explaining below example.
<profiles>
   <profile>
     <id>test</id>
     <build>
       <plugins>
         <plugin>
           <artifactId>maven-antrun-plugin</artifactId>
           <executions>
             <execution>
               <phase>test</phase>
               <goals>
                 <goal>run</goal>
               </goals>
               <configuration>
                 <tasks>
                   <delete file="${project.build.outputDirectory}/environment.properties"/>
                   <copy file="src/main/resources/environment.test.properties"
                         tofile="${project.build.outputDirectory}/environment.properties"/>
                 </tasks>
               </configuration>
             </execution>
           </executions>
         </plugin>
         <plugin>
           <artifactId>maven-surefire-plugin</artifactId>
           <configuration>
             <skip>true</skip>
           </configuration>
         </plugin>
         <plugin>
           <artifactId>maven-jar-plugin</artifactId>
           <executions>
             <execution>
               <phase>package</phase>
               <goals>
                 <goal>jar</goal>
               </goals>
               <configuration>
                 <classifier>test</classifier>
               </configuration>
             </execution>
           </executions>
         </plugin>
       </plugins>
     </build>
   </profile>

   .. Other profiles go here ..

 </profiles>

Three things are configured in this snippet:

  1. It configures the antrun plugin to execute the run goal in the test phase where it will copy the environment.test.properties file to environment.properties.
  2. It will configure the test plugin to skip all tests when building the test and production artifacts. This is useful as you probably don’t want to run tests against the production system
  3. It configures the JAR plugin to create an “attached” JAR with the “test” classifier.To activate this profile execute mvn -Ptest install and Maven will execute the steps in the profile in addition to the normal steps. From this build you will get two artifacts, “foo-1.0.jar” and “foo-1.0-test.jar”. These two jars will identical.

Cons :

  • After the build, test configuration will be in target/classes and won’t be overridden because the resources plugin uses the same timestamp checking, so you should always do a clean after executing Maven with a profile.
  • For the reasons given above you should build an artifact for a single environment in a single execution at a time and then you execute “mvn clean” whenever you change the profile switches. If not, you might get artifacts with a mixed set of configuration files.

Which areas of a POM can be customized by profile in POM?

Profiles specified in the POM can modify the following POM elements:

  • <repositories>
  • <pluginRepositories>
  • <dependencies>
  • <plugins>
  • <properties> (not actually available in the main POM, but used behind the scenes)
  • <modules>
  • <reporting>
  • <dependencyManagement>
  • <distributionManagement>
  • a subset of the <build> element, which consists of:
    • <defaultGoal>
    • <resources>
    • <testResources>
    • <finalName>

Conclusion

By the way, we had a quick look on following in this article,

  1. What is build profile in maven
  2. How to implement build profiles in POM of the project
  3. How to build project based on profile
  4. What elements can be modified in POM by profiles
Please follow and like us:
error