How to Use Maven Profiles to Selectively Activate Plugins and Other Configurations from the Command Line

Apache Maven is a software project management and build tool favored by many Java and Kotlin developers, as well as those developing for the JVM. In this post, I explain how you can define profiles in your Maven pom.xml that you can activate selectively from the command line at the time of your build. There can be many reasons for using this feature. For example, perhaps you deploy build artifacts to different Maven repositories, each requiring different configuration. Or perhaps there’s a plugin that you only want to run during some (but not all) builds. Profiles can be used to accomplish both of these.

We will use two examples. In the first, we will use a profile to activate selectively jacoco-maven-plugin To generate a code coverage report during the Maven testing phase, but only when the profile has been activated on the command line. In the second example, we will use the case of deploying artifacts to both the Maven Central repository as well as the GitHub package.

Table of Contents:

how to specify profile

Before jumping into specific examples, let’s start with an explanation of how to define a profile in your pom.xml, To do this, you would add a profile section to your pom.xml with the following:

<profiles>

</profiles>
enter fullscreen mode

exit fullscreen mode

In that Profile section, you then add one or more profiles. We are going to focus on profiles that are activated with command line options. To use that feature, we need to give each of our profiles an ID. The ID of the profile is what we will use on the command line to activate it.

<profiles>
    <profile>
        <id>profileOne</id>

    </profile>
    <profile>
        <id>profileTwo</id>

    </profile>
    <profile>
        <id>profileThree</id>

    </profile>
</profiles>
enter fullscreen mode

exit fullscreen mode

In the above, we have three profiles with id profileOne, profileTwoAnd profileThree, To activate a profile from the command line at the time of your build, you use the command line option -P, For example, the following command fires profileTwo while executing package Lifecycle Stages:

mvn package -PprofileTwo
enter fullscreen mode

exit fullscreen mode

The next two sections of this post provide more specific examples of what you can use a profile for.

Profile to activate (de)enable a plugin at build time

One of the ways I sometimes use maven profiles is if there’s a plugin I want to use sometimes. Instead of configuring it normally <build></build> section of pom.xml, you instead configure it in an additional <build></build> section within a profile. Here’s a typical example of what it would look like:

<profiles>
    <profile>
        <id>profileOne</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>com.example</groupId>
                    <artifactId>example-plugin</artifactId>
                    <version>1.2.3</version>

                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
enter fullscreen mode

exit fullscreen mode

Above we see a profile named profileOne version that includes 1.2.3 of a plugin named example-plugin with groupId of com.example, Any configuration needed for that plugin will be put in there as well. note that our pom.xml would be normal <build></build> The section is elsewhere that we’ll use to configure all of our other plugins.

A typical example where I regularly use a profile like this is to configure code coverage. In all my Java projects, I use Jacoco to generate code coverage reports. I use JaCoCo during Maven testing phase. However, when developing I find it useful at times to exclude coverage reporting to reduce build times. But in my CI/CD workflow in GitHub Actions, I activate the code coverage profile during pull-requests and push to the default branch. For pull-requests, my GitHub Actions comment out the code coverage on a workflow PR and upload the coverage report as a workflow artifact, where I can inspect it as needed. And while pushing the default branch, my workflow updates the coverage badges to keep them up to date with the current status of the default branch. I can also activate the code coverage profile locally while developing, such as before submitting a pull-request, to make sure I didn’t miss testing something.

Here’s a typical example from a library I’ve found called chips-n-salsa, where I’ve configured Jacoco code coverage using a Maven profile like this.

<profiles>
    <profile>
        <id>coverage</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>0.8.8</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>prepare-agent</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>generate-code-coverage-report</id>
                            <phase>test</phase>
                            <goals>
                                <goal>report</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
enter fullscreen mode

exit fullscreen mode

In the above example, JaCoCo is configured to generate a coverage report during the Maven test phase. But because I put it in a profile (named here coverage), instead of regular <build></build> section, we need to activate coverage From the command line at the time of profile creation, with the following:

mvn test -Pcoverage
enter fullscreen mode

exit fullscreen mode

or, we can use mvn package or something else that includes a test phase, something like:

mvn package -Pcoverage
enter fullscreen mode

exit fullscreen mode

Profiles for deployment to multiple Maven repositories

Are plugins the only thing you can configure in a Maven profile? No, they are not. They are also highly useful if you regularly deploy artifacts to multiple Maven repositories. Here’s an example:

<profiles>
    <profile>
        <id>profileOne</id>
        <distributionManagement>
            <repository>
                <id>repo1</id>
                <name>Name of Repo 1</name>
                <url>https://example.com/url/of/repo1</url>
            </repository>
        </distributionManagement>
    </profile>
    <profile>
        <id>profileTwo</id>
        <distributionManagement>
            <repository>
                <id>repo2</id>
                <name>Name of Repo 2</name>
                <url>https://example.com/url/of/repo2</url>
            </repository>
        </distributionManagement>
    </profile>
</profiles>
enter fullscreen mode

exit fullscreen mode

The above example defines two profiles, profileOne And profileTwoto deploy artifacts to two different maven repositories. <distributionManagement> section of a pom.xml allows specifying only one <repository> (though you can also specify a <snapshotRepository>) profiles provide a way to configure more than one, such that we activate at most one from the command line during deployment.

With the above example, if we want to deploy repo1we use:

mvn deploy -PprofileOne
enter fullscreen mode

exit fullscreen mode

and if we want to deploy repo2we use:

mvn deploy -PprofileTwo
enter fullscreen mode

exit fullscreen mode

Let’s look at a real example, again from chips-n-salsa, where I publish library artifacts to both Maven Central as well as GitHub packages. We will create a complete example. First, consider <distributionManagement> below configuration:

<profiles>
    <profile>
        <id>githubDeploy</id>
        <distributionManagement>
            <repository>
                <id>github</id>
                <name>GitHub cicirello Apache Maven Packages</name>
                <url>https://maven.pkg.github.com/cicirello/Chips-n-Salsa</url>
            </repository>
        </distributionManagement>
    </profile>
    <profile>
        <id>ossrhDeploy</id>
        <distributionManagement>
            <repository>
                <id>ossrh</id>
                <name>Central Repository OSSRH</name>
                <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
            </repository>
        </distributionManagement>
    </profile>
</profiles>
enter fullscreen mode

exit fullscreen mode

So far it is the same as the normal example before. However, we are not completely. githubDeploy Profiles is all we need for GitHub packages. However, we need a little more for Maven Central. Specifically, there are some plugins that we need to add to ossrhDeploy profile above. Maven Central requires that all of our artifacts be signed with GPG. So we will need to configure the plugin maven-gpg-plugin, Additionally, for Maven Central, our artifacts will end up in a Sonatype staging repository initially. To avoid the need to login to release manually from staging, we will configure nexus-staging-maven-plugin To do this for us.

Here is the complete example:

<profiles>
    <profile>
        <id>githubDeploy</id>
        <distributionManagement>
            <repository>
                <id>github</id>
                <name>GitHub cicirello Apache Maven Packages</name>
                <url>https://maven.pkg.github.com/cicirello/Chips-n-Salsa</url>
            </repository>
        </distributionManagement>
    </profile>
    <profile>
        <id>ossrhDeploy</id>
        <distributionManagement>
            <repository>
                <id>ossrh</id>
                <name>Central Repository OSSRH</name>
                <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
            </repository>
        </distributionManagement>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-gpg-plugin</artifactId>
                    <version>3.0.1</version>
                    <executions>
                        <execution>
                            <id>sign-artifacts</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>sign</goal>
                            </goals>
                            <configuration>
                                <gpgArguments>
                                    <arg>--pinentry-mode</arg>
                                    <arg>loopback</arg>
                                </gpgArguments>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.sonatype.plugins</groupId>
                    <artifactId>nexus-staging-maven-plugin</artifactId>
                    <version>1.6.13</version>
                    <extensions>true</extensions>
                    <configuration>
                        <serverId>ossrh</serverId>
                        <nexusUrl>https://oss.sonatype.org/</nexusUrl>
                        <autoReleaseAfterClose>true</autoReleaseAfterClose>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
enter fullscreen mode

exit fullscreen mode

Given the above in pom.xml, to deploy to Maven Central, we use:

mvn deploy -PossrhDeploy
enter fullscreen mode

exit fullscreen mode

Or to deploy to GitHub packages instead, we use:

mvn deploy -PgithubDeploy
enter fullscreen mode

exit fullscreen mode

live example

To see a live example of both of these uses of Maven profiles, consult the pom.xml of one of my projects. Here is the GitHub repository:

A Java library of customizable, hybridizable, iterative, parallel, stochastic, and self-adaptive local search algorithms

Copyright (c) 2002-2022 Vincent A. Cicirello.

Website: https://chips-n-salsa.ciciirello.org/

API Documentation: https://chips-n-salsa.ciciirello.org/api/

how to quote

If you use this library in your research, please cite the following paper:

Cicirello, VA, (2020). Chips-n-Salsa: A Java library of customizable, hybridizable, iterative, parallel, stochastic, and self-adaptive local search algorithms. Journal of Open Source Software5(52), 2448, https://doi.org/10.21105/joss.02448.

Observation

Chips-n-Salsa is a Java library of customizable, hybridizable, iterative, parallel, stochastic and self-adaptive local search algorithms. The library includes implementations of several stochastic local search algorithms, including simulated annealing, hill climbers, as well as constructive search algorithms such as stochastic sampling. Chips-n-Salsa now includes genetic algorithms as well as evolutionary algorithms more generally. The library supports simulated annealing very widely. It consists of several classes to represent solutions to various optimization problems. For…

Where you can find me

Follow me on dev here:

Cicirello Image

Follow me on GitHub:

Vincent A Cicirello

my bibliography

my github activity

If you want to generate the equivalent of the above for your own GitHub profile, check out the Cicirello/user-statisticians GitHub Actions.

or visit my website:

Vincent A. Cicirello – professor of computer science at Stockton University – is a researcher in artificial intelligence, evolutionary computation, swarm intelligence, and computational intelligence, with a PhD. in Robotics from Carnegie Mellon University. He is an ACM Senior Member, IEEE Senior Member, AAAI Life Member, EAI Distinguished Member and SIAM Member.

favicon
cicirello.org

Leave a Comment