Maven Build Profiles
Build profiles are a set of configuration values that can be used to set or override default values in a Maven build.
Using build profiles, you can tailor the build process for different environments, such as Production and Development environments.
Profiles are specified in the pom.xml file using the activeProfiles
or profiles
elements and can be triggered in various ways. Profiles modify the POM during the build process and are used to set parameters for different target environments (e.g., database server addresses in Development, Testing, and Production environments).
Types of Build Profiles
There are three main types of build profiles:
Type | Defined in |
---|---|
Per Project | Defined in the project's POM file (pom.xml) |
Per User | Defined in Maven's settings XML file (%USER_HOME%/.m2/settings.xml) |
Global | Defined in Maven's global settings XML file (%M2_HOME%/conf/settings.xml) |
Profile Activation
Maven build profiles can be activated in several ways:
- Explicitly activated via the command console.
- Through Maven settings.
- Based on environment variables (user or system variables).
- Operating system settings (e.g., Windows).
- The presence or absence of files.
Profile Activation Example
Assume the project structure is as follows:
There are three test files in the src/main/resources
folder:
File Name | Description |
---|---|
env.properties | Default configuration used when no profile is specified. |
env.test.properties | Configuration used when the test profile is active. |
env.prod.properties | Configuration used when the production profile is active. |
Note: These configuration files do not represent the functionality of build profiles but are for testing purposes. For example, when the build profile is set to prod
, the project uses the env.prod.properties
file.
Note: The following example still uses the AntRun plugin because it can bind to Maven lifecycle phases and output information, copy files, etc., without writing any code. This is unrelated to the build profiles.
1. Profile Activation
Profiles allow us to define a set of configuration information and specify their activation conditions. This way, we can define multiple profiles, each with different activation conditions and configuration information, to achieve different configurations for different environments.
In the following example, we add the maven-antrun-plugin:run
goal to the test phase. This allows us to output text information in different profiles. We will define different profiles in the pom.xml
and activate them using Maven commands in the command console.
The pom.xml
file is as follows:
<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>com.jsoft.test</groupId>
<artifactId>testproject</artifactId>
<packaging>jar</packaging>
<version>0.1-SNAPSHOT</version>
<name>testproject</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>
<profile>
<id>test</id>
<build>
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>Using env.test.properties</echo> <copy file="src/main/resources/env.test.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>normal</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>Using env.properties</echo> <copy file="src/main/resources/env.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.prod.properties</echo>
<copy file="src/main/resources/env.prod.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Note: The build configuration file uses the <profiles> node.
Explanation: Three <profiles> have been created above, where <id> distinguishes different <profiles> to execute different AntRun tasks. AntRun tasks can be understood as follows: AntRun listens to the Maven lifecycle phase of test. When Maven executes the test phase, it triggers the AntRun tasks, which output text and copy files to specified locations. As for which AntRun task to execute, the build configuration file serves as the transmission directive. For example, by inputting a specified <id> via command line arguments.
Execution command:
mvn test -Ptest
Hint: The first "test" is the Maven lifecycle phase, and the second "test" is the <id> parameter specified by the build configuration file, which is transmitted via -P
. Of course, it can be "prod" or "normal", which are defined by you.
The result of the run is as follows:
It can be seen that the AntRun task was successfully triggered, corresponding to the <id> of "test" under the build configuration file.
Testing the other two commands, the results are as follows:
2. Activating Profiles via Maven Settings
Open the settings.xml file in the %USERHOME%/.m2 directory, where %USERHOME% represents the user's home directory. If the settings.xml file does not exist, copy %M2HOME%/conf/settings.xml to the .m2 directory, where %M2HOME% represents the Maven installation directory.
Configure the settings.xml file by adding the <activeProfiles>
attribute:
<settings 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/xsd/settings-1.0.0.xsd">
...
<settings>
<activeProfiles>
<activeProfile>test</activeProfile>
</activeProfiles>
</settings>
Execute command:
mvn test
Note 1: At this point, you do not need to use -Ptest to specify the parameter, as the <activeProfile> in the setting.xml file has already specified the test parameter.
Note 2: Similarly, you can configure the settings in the %M2_HOME%/conf/settings.xml file with the same effect.
Execution result:
3. Activating Profiles via Environment Variables
First, remove all values from the previous test setting.xml.
Then, add an <activation> node to the <profile> node with <id>test</id> in the pom.xml:
<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>com.jsoft.test</groupId>
<artifactId>testproject</artifactId>
<packaging>jar</packaging>
<version>0.1-SNAPSHOT</version>
<name>testproject</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>
<profile>
<id>test</id>
<activation>
<property>
<name>env</name>
<value>test</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>Using env.test.properties</echo>
<copy file="src/main/resources/env.test.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/>
</tasks>
</configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>normal</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>Using env.properties</echo> <copy file="src/main/resources/env.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> <profile> <id>prod</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <echo>Using env.prod.properties</echo> <copy file="src/main/resources/env.prod.properties" tofile="${project.build.outputDirectory}/env.properties" overwrite="true"/> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Execute the command:
mvn test -Denv=test
Hint 1: The above command uses -D to pass environment variables, where env corresponds to the <name> value set earlier, and test corresponds to the <value>.
Hint 2: The system environment variables were tested on Windows 10 but did not take effect, so they can only be passed via -D
.
Execution result: