Development, test and production environments often need different configurations (database addresses, log levels, and so on). Maven’s Profile mechanism was designed to solve exactly this problem.
Defining a Profile
In pom.xml:
<profiles>
<profile>
<id>dev</id>
<properties>
<env.name>development</env.name>
<db.url>jdbc:mysql://localhost:3306/dev_db</db.url>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<env.name>production</env.name>
<db.url>jdbc:mysql://prod-server:3306/prod_db</db.url>
</properties>
</profile>
</profiles>
Activating a Profile
# Activate a single one
mvn package -Pdev
mvn package -Pprod
# Activate several
mvn package -Pdev,debug
# Exclude one (when prod has activeByDefault)
mvn package -P!prod
Using it together with resource filtering
In src/main/resources/application.properties:
env.name=${env.name}
db.url=${db.url}
Then enable filtering in the <build> section of pom.xml:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
At packaging time Maven replaces ${env.name} with the value from the corresponding Profile.
Automatic activation by condition
<!-- Triggered by JDK version -->
<activation>
<jdk>[11,)</jdk>
</activation>
<!-- Triggered by operating system -->
<activation>
<os>
<name>Windows 10</name>
<family>windows</family>
</os>
</activation>
<!-- Triggered by presence of a property -->
<activation>
<property>
<name>ci</name>
</property>
</activation>
Defining a global Profile in settings.xml
~/.m2/settings.xml (shared by all projects):
<profiles>
<profile>
<id>company-repo</id>
<repositories>
<repository>
<id>internal</id>
<url>https://nexus.company.com/repository/maven-public/</url>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>company-repo</activeProfile>
</activeProfiles>
Overriding dependencies in a Profile
<profile>
<id>local</id>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>mock-service</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</profile>
For local development use a mock implementation, and for production use the real implementation.
Viewing the currently active Profile
mvn help:active-profiles
A small step forward every day is a new height!