Maven: The Complete Reference

5.2. Portability through Maven Profiles

A profile in Maven is an alternative set of configuration values which set or override default values. Using a profile, you can customize a build for different environments. Profiles are configured in the pom.xml and are given an identifier. Then you can run Maven with a command-line flag that tells Maven to execute goals in a specific profile. The following pom.xml uses a production profile to override the default settings of the Compiler plugin.

Using a Maven Profile to Override Production Compiler Settings. 

<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>org.sonatype.mavenbook</groupId>
    <artifactId>simple</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>simple</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <profiles> (1)
            <profile>
                <id>production</id> (2)
                    <build> (3)
                            <plugins>
                                <plugin>
                                    <groupId>org.apache.maven.plugins</groupId>
                                    <artifactId>maven-compiler-plugin</artifactId>
                                    <configuration>
                                        <debug>false</debug> (4)
                                            <optimize>true</optimize>
                                    </configuration>
                                </plugin>
                            </plugins>
                    </build>
            </profile>
    </profiles>
</project>

In this example, we’ve added a profile named production that overrides the default configuration of the Maven Compiler plugin. Let’s examine the syntax of this profile in detail.

(1)

The profiles element is in the pom.xml, it contains one or more profile elements. Since profiles override the default settings in a pom.xml, the profiles element is usually listed as the last element in a pom.xml.

(2)

Each profile has to have an id element. This id element contains the name which is used to invoke this profile from the command-line. A profile is invoked by passing the -P<profile_id> command-line argument to Maven.

(3)

A profile element can contain many of the elements which can appear under the project element of a POM XML Document. In this example, we’re overriding the behavior of the Compiler plugin and we have to override the plugin configuration which is normally enclosed in a build and a plugins element.

(4)

We’re overriding the configuration of the Maven Compiler plugin. We’re making sure that the bytecode produced by the production profile doesn’t contain debug information and that the bytecode has gone through the compiler’s optimization routines.

To execute mvn install under the production profile, you need to pass the -Pproduction argument on the command-line. To verify that the production profile overrides the default Compiler plugin configuration, execute Maven with debug output enabled (-X) as follows:

~/examples/profile $ mvn clean install -Pproduction -X
... (omitting debugging output) ...
[DEBUG] Configuring mojo 'o.a.m.plugins:maven-compiler-plugin:2.0.2:testCompile'
[DEBUG]   (f) basedir = ~\examples\profile
[DEBUG]   (f) buildDirectory = ~\examples\profile\target
...
[DEBUG]   (f) compilerId = javac
[DEBUG]   (f) *debug = false*
[DEBUG]   (f) failOnError = true
[DEBUG]   (f) fork = false
[DEBUG]   (f) *optimize = true*
[DEBUG]   (f) outputDirectory = \
~\svnw\sonatype\examples\profile\target\test-classes
[DEBUG]   (f) outputFileName = simple-1.0-SNAPSHOT
[DEBUG]   (f) showDeprecation = false
[DEBUG]   (f) showWarnings = false
[DEBUG]   (f) staleMillis = 0
[DEBUG]   (f) verbose = false
[DEBUG] -- end configuration --
... (omitting debugging output) ...

This excerpt from the debug output of Maven shows the configuration of the Compiler plugin under the production profile. As shown in the output, debug is set to false and optimize is set to true.

5.2.1. Overriding a Project Object Model

While the previous example showed you how to override the default configuration properties of a single Maven plugin, you still don’t know exactly what a Maven profile is allowed to override. The short-answer to that question is that a Maven profile can override almost everything that you would have in a pom.xml. The Maven POM contains an element under project called profiles containing a project’s alternate configurations, and under this element are profile elements which define each profile. Each profile must have an id, and other than that, it can contain almost any of the elements one would expect to see under project. The following XML document shows all of the elements, a profile is allowed to override.

Elements Allowed in a Profile. 

<project>
    <profiles>
        <profile>
            <build>
                <defaultGoal>...</defaultGoal>
                <finalName>...</finalName>
                <resources>...</resources>
                <testResources>...</testResources>
                <plugins>...</plugins>
            </build>
            <reporting>...</reporting>
            <modules>...</modules>
            <dependencies>...</dependencies>
            <dependencyManagement>...</dependencyManagement>
            <distributionManagement>...</distributionManagement>
            <repositories>...</repositories>
            <pluginRepositories>...</pluginRepositories>
            <properties>...</properties>
        </profile>
    </profiles>
</project>

A profile can override an element shown with ellipses. A profile can override the final name of a project’s artifact in a profile, the dependencies, and the behavior of a project’s build via plugin configuration. A profile can also override the configuration of distribution settings depending on the profile; for example, if you need to publish an artifact to a staging server in a staging profile, you would create a staging profile which overrides the distributionManagement element in a profile.