Main Tutorials

Maven Profiles example

In this article, we will show you few Maven profile examples to pass different parameters (server or database parameters) for different environments (dev, test or prod).

P.S Tested with Maven 3.5.3

1. Basic Maven Profiles

1.1 A simple profile to skip the unit test.

pom.xml

	<!-- skip unit test -->
	<profile>
		<id>xtest</id>
		<properties>
			<maven.test.skip>true</maven.test.skip>
		</properties>
	</profile>

1.2 To activate a profile, add -P option.

Terminal

# Activate xtest profile to skip unit test and package the project
  
$ mvn package -Pxtest

1.3 To activate multiple profiles :

Terminal

$ mvn package -P xtest, another-profile-id

# multi modules, same syntax
$ mvn -pl module-name package -P xtest, another-profile-id

1.4 Always add maven-help-plugin to display the active profile during the compile or package phase, it will save you a lot of debugging time.

pom.xml

	<build>
        <plugins>
            <!-- display active profile in compile phase -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-help-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>show-profiles</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>active-profiles</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

Next time, the current active profile will be displayed in compile phase.

Terminal

$ mvn compile -P xtest

[INFO] --- maven-help-plugin:3.1.0:active-profiles (show-profiles) @ example1 ---
[INFO]
Active Profiles for Project 'com.mkyong:example1:jar:1.0':

The following profiles are active:

 - xtest (source: com.mkyong:example1:1.0)

2. Maven Profiles – Example 1

Maven profile example to pass different properties values to development and production environments.

2.1 A properties file.

resources/db.properties

db.driverClassName=${db.driverClassName}
db.url=${db.url}
db.username=${db.username}
db.password=${db.password}

2.2 Enable the filtering. Maven will map the ${} in resources/db.properties with the active Maven profile properties.

Note
Read this Maven filtering
pom.xml

        <!-- map ${} variable -->
	<resources>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
		</resource>
	</resources>

2.3 Create two profiles ids (dev and prod) with different properties values.

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>maven-profiles</artifactId>
        <groupId>com.mkyong</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>example1</artifactId>

    <profiles>

        <profile>
            <id>dev</id>
            <activation>
                <!-- this profile is active by default -->
                <activeByDefault>true</activeByDefault>
                <!-- activate if system properties 'env=dev' -->
                <property>
                    <name>env</name>
                    <value>dev</value>
                </property>
            </activation>
            <properties>
                <db.driverClassName>com.mysql.jdbc.Driver</db.driverClassName>
                <db.url>jdbc:mysql://localhost:3306/dev</db.url>
                <db.username>mkyong</db.username>
                <db.password>8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92</db.password>
            </properties>
        </profile>

        <profile>
            <id>prod</id>
            <activation>
                <!-- activate if system properties 'env=prod' -->
                <property>
                    <name>env</name>
                    <value>prod</value>
                </property>
            </activation>
            <properties>
                <db.driverClassName>com.mysql.jdbc.Driver</db.driverClassName>
                <db.url>jdbc:mysql://live01:3306/prod</db.url>
                <db.username>mkyong</db.username>
                <db.password>8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92</db.password>
            </properties>
        </profile>

    </profiles>

    <build>

        <!-- map ${} variable -->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>

        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.mkyong.example1.App1</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

</project>

2.4 Loads the properties file and print it out.

App1.java

package com.mkyong.example1;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class App1 {

    public static void main(String[] args) {

        App1 app = new App1();
        Properties prop = app.loadPropertiesFile("db.properties");
        prop.forEach((k, v) -> System.out.println(k + ":" + v));

    }

    public Properties loadPropertiesFile(String filePath) {

        Properties prop = new Properties();

        try (InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(filePath)) {
            prop.load(resourceAsStream);
        } catch (IOException e) {
            System.err.println("Unable to load properties file : " + filePath);
        }

        return prop;

    }
}

2.5 Test it.

Terminal

# default profile id is 'dev'
$ mvn package

$ java -jar target/example1-1.0.jar
db.password:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
db.driverClassName:com.mysql.jdbc.Driver
db.username:mkyong
db.url:jdbc:mysql://localhost:3306/dev

# enable profile id 'prod' with -P prod or -D env=prod
$ mvn package -P prod
$ mvn package -D env=prod

$ java -jar target/example1-1.0.jar
db.password:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
db.driverClassName:com.mysql.jdbc.Driver
db.username:mkyong
db.url:jdbc:mysql://live01:3306/prod

3. Maven Profiles – Example 2

This Maven profile example will put everything in the properties file.

3.1 A properties file, later Maven will map the value depend on the profile id.

resources/config.properties

# Database Config
db.driverClassName=${db.driverClassName}
db.url=${db.url}
db.username=${db.username}
db.password=${db.password}

# Email Server
email.server=${email.server}

# Log Files
log.file.location=${log.file.location}

3.2 Create different properties files for dev,test and production environment.

resources/env/config.dev.properties

# Database Config
db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/dev
db.username=mkyong
db.password=8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92

# Email Server
email.server=email-dev:8888

# Log Files
log.file.location=dev/file.log
resources/env/config.test.properties

# Database Config
db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://test01:3306/test
db.username=mkyong
db.password=8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92

# Email Server
email.server=email-test:8888

# Log Files
log.file.location=test/file.log
resources/env/config.prod.properties

# Database Config
db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://live01:3306/prod
db.username=mkyong
db.password=8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92

# Email Server
email.server=email-prod:25

# Log Files
log.file.location=prod/file.log

3.3 Enable the filtering. This is the key!

Note
Read this Maven filtering
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>maven-profiles</artifactId>
        <groupId>com.mkyong</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>example2</artifactId>

    <profiles>

        <profile>
            <id>dev</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <env>dev</env>
            </properties>
        </profile>

        <profile>
            <id>prod</id>
            <properties>
                <env>prod</env>
            </properties>
        </profile>

        <profile>
            <id>test</id>
            <properties>
                <env>test</env>
            </properties>
        </profile>

    </profiles>

    <build>

        <!-- Loading all ${} -->
        <filters>
            <filter>src/main/resources/env/config.${env}.properties</filter>
        </filters>

        <!-- Map ${} into resources -->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>*.properties</include>
                </includes>
            </resource>
        </resources>

        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.mkyong.example2.App2</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>

    </build>

</project>

3.4 Loads the properties file and print it out.

App1.java

package com.mkyong.example2;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class App2 {

    public static void main(String[] args) {

        App2 app = new App2();
        Properties prop = app.loadPropertiesFile("config.properties");
        prop.forEach((k, v) -> System.out.println(k + ":" + v));

    }

    public Properties loadPropertiesFile(String filePath) {

        Properties prop = new Properties();

        try (InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(filePath)) {
            prop.load(resourceAsStream);
        } catch (IOException e) {
            System.err.println("Unable to load properties file : " + filePath);
        }

        return prop;

    }

}

3.5 Test it.

Terminal

# profile id dev (default) 
$ mvn package

$ java -jar target/example2-1.0.jar
log.file.location:dev/file.log
db.password:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
db.driverClassName:com.mysql.jdbc.Driver
db.username:mkyong
email.server:email-dev:8888
db.url:jdbc:mysql://localhost:3306/dev

# profile id prod
$ mvn package -P prod

$ java -jar target/example2-1.0.jar
log.file.location:prod/file.log
db.password:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
db.driverClassName:com.mysql.jdbc.Driver
db.username:mkyong
email.server:email-prod:25
db.url:jdbc:mysql://live01:3306/prod

# profile id test
$ mvn package -P test

$ java -jar target/example2-1.0.jar
log.file.location:test/file.log
db.password:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
db.driverClassName:com.mysql.jdbc.Driver
db.username:mkyong
email.server:email-test:8888
db.url:jdbc:mysql://test01:3306/test

The end, let me know your use case 🙂

Download Source Code

$ git clone https://github.com/mkyong/maven-examples.git
$ cd maven-profiles

# Test the example 1 with profile ‘prod’
$ mvn -pl example1 package -Pprod
$ java -jar example1/target/example1-1.0.jar

# Test the example 2 with profile ‘test’
$ mvn -pl example2 package -Ptest
$ java -jar example2/target/example2-1.0.jar

References

  1. Introduction to Build Profiles
  2. Maven Best Practices
  3. Building For Different Environments with Maven 2
  4. Maven Filtering

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
11 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Rahul
4 years ago

Hi
my question is. How we can pass the command line parameter while deployment (on tomacat ) so in production mode i can pass value as “prod “

monsio
4 years ago

Thanks for that tutorial.

If you use spring boot replace ${var} with @var@ in your configuration files

abhinav
1 year ago
Reply to  monsio

Thanks a lot !!

Arne
8 months ago

Can you please share on how to run your examples building both profiles at the same time? I guess the properties will be overwritten with the last profile of the maven execution. Properties seem not be isolated for the single profile only. Please try running

mvn package -P test, prod

to release for both environments.

Anand
2 years ago

loved it

Menish
2 years ago

hi,

I have two profiles for my project each based on different environments, each profile also has a specific class, how can I assign the class to the profiles. In spring there is the @Profile annotation but I am not using spring, rather java ee. Many thanks in advance for any suggestions.

Gustavo
2 years ago

hi my question is for example 3
if i have two files
config.properties and log4j.properties how can it work
with a package than includes conf.qa.properties and log4j.qa.properties

    <filters>
        <filter>src/main/resources/com/config.${com}.properties</filter>
                <filter>src/main/resources/com/regional/log4j.${com}.properties</filter>
    </filters>
    <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
             </resource>
     </resources>
           
JohnKowalsky
2 years ago

Eclipse 2020-12 shows errors in example1 and example2 POMs:
“Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-help-plugin:3.1.0:active-profiles (execution: show-profiles, phase: compile)”

Addition of “pluginManagement” tag in parent’s POM solved the issue.
<build>
<pluginManagement>
<plugins>

</plugins>
</pluginManagement>
</build>

Paco
3 years ago

Very good,
thanks

Surya
3 years ago

Hi Mkyong,

I found your articles very informative. Thank you for sharing these information.
I am working on Maven and creating poms with profiles. I am stuck on one issue wherein maven resources plugin is getting skipped during build with profile. All the execution’s configurations are not getting executed for copy resources goal. I have tried changing the phase as to generate resources,package resources etc but none worked.

Without defining profile sections in the pom, my project is getting build correctly. I am suspecting when I am defining profiles in the pom, it is not identifying maven resources plugin at all.

Could you please throw some light on where is the mistake and if I need to use any other copy plugin under profile section.

Thank you.

sumedha
3 years ago

Thanks for tutorial. really good examples