Set up multiple profiles in maven

Maven là một build management tool được sử dụng phổ biến trong các dự án Java, Trong vòng đời phát triển của một dự án, phần mềm phải chạy trên cái môi trường khác nhau: production, development và test Trong bài viết này chúng ta sẽ sử dụng Maven để config các file cấu hình hay các properties file trong các môi trường khác nhau.

  • Step1: Tạo một maven project có file pom.xml như dưới đây
<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.framgia</groupId>
    <artifactId>profiles-config</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
          </resource>
          <resource>
            <directory>src/main/resources-filter</directory>
            <filtering>true</filtering>
          </resource>
          <resource>
            <directory>src/main/resources-${env}</directory>
          </resource>
          <resource>
            <directory>src/main/java</directory>
            <excludes>
              <exclude>**/*.java</exclude>
            </excludes>
          </resource>
        </resources>
        <testResources>
          <testResource>
            <directory>src/test/resources</directory>
          </testResource>
          <testResource>
            <directory>src/test/java</directory>
            <excludes>
              <exclude>**/*.java</exclude>
            </excludes>
          </testResource>
        </testResources>
        <pluginManagement>
            <plugins>
            <!--Specify the encoding for copying resources-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <configuration>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <profiles>
        <profile>
          <id>devel</id>
           <!--
          <activation>
            <activeByDefault>true</activeByDefault>
          </activation>
          -->
          <properties>
            <context>default</context>
            <env>devel</env>
          </properties>
        </profile>
        <profile>
          <id>release</id>
           <activation>
            <activeByDefault>true</activeByDefault>
          </activation>
          <properties>
            <context>default</context>
            <env>release</env>
          </properties>
        </profile>
        <profile>
          <id>testing</id>
        <!--
          <activation>
            <activeByDefault>true</activeByDefault>
          </activation>
          -->
          <properties>
            <context>default</context>
            <env>testing</env>
          </properties>
        </profile>
    </profiles>
</project>

Điều quan trọng nhất ở đây là file pom ở trên đã khai báo một tag <profiles> trong tag profiles có thể định nghĩa các <profile> khác nhau là: release, devel và testing. Để activate một profile dùng thẻ <activation>

 <activation>
        <activeByDefault>true</activeByDefault>
  </activation>

Do mỗi một môi trường có các file config hay file properties khác nhau, nên chúng ta sẽ tạo các resources folder cho từng môi trường này như hình dưới đây:

Mặc định thì maven project sẽ load tất cả các resources files từ các folder resource mặc định là resources, để load được các customized resources folder: resources-devel, resources-release và resources-testing mà chúng ta vừa tạo thì cần phải khai báo trong tag resource trong maven

        <resources>
          <resource>
            <directory>src/main/resources-${env}</directory>
          </resource>
      </resources>

Biến ${env} sẽ được lấy từ active profile mà chúng ta đã định nghĩa trong thẻ <activation> ở trên Đến đây mọi config cho profile đã hoàn tất, hãy lấy một ví dụ

  • Step2: Ví dụ

Tạo các properties file trong các môi trường khác nhau: application.properties

com.framgia.env=development
  • Khai báo PropertyReader class
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropertyReader {
    public static String getEnvironment() throws IOException {
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        InputStream input = classloader.getResourceAsStream("application.properties");
        final Properties properties = new Properties();
        properties.load(input);
        return properties.getProperty("com.framgia.env");
    }
}

Viết test để check xem liệu logic có lấy đúng value trong properties file theo active profile hay không:

import org.junit.Test;

import java.io.IOException;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class PropertyReaderTest {

    @Test
    public void getEnvironment_shouldReturnCorrectEnv() throws IOException {
        assertThat(PropertyReader.getEnvironment(), is("development"));
    }
}

Test passed như vậy đã load thành công properties file, để test cho các profile khác hãy thay đổi active profile trong pom file và chạy test lại