Using Maven profile and filtering to package various environments

Time:2021-3-4

Each project will have multiple running environments (development, testing, formal, etc.) and different environment configurations (e.g jdbc.url )With the convenience of Jenkins and automatic deployment, we can separate the configuration files of different environments, and replace the packaged files with the configuration files of corresponding environments after packaging. In fact, Maven has provided us with a replacement Replacement scheme:profile + filtering

Filtering

Filtering is a function provided by Maven’s resource plug-in. Its function is to replace attributes with environment variables, attributes defined in POM files and attributes in specified configuration files(*.properties)A place holder in a file(${jdbc.url})The specific use is as follows:
staysrc/main/resourcesThe directory has a configuration filejdbc.propertiesThe contents are as follows:

jdbc.url=${pom.jdbc.url}
jdbc.username=${pom.jdbc.username}
jdbc.passworkd=${pom.jdbc.password}

Configure the resource plug-in, enable the filtering function and add attributes to POM:

<project>
    ...
    <! -- replace with the attributes defined in POM -- >    
    <properties>
        <pom.jdbc.url>jdbc:mysql://127.0.0.1:3306/dev</pom.jdbc.url>
        <pom.jdbc.username>root</pom.jdbc.username>
        <pom.jdbc.password>123456</pom.jdbc.password>
    </properties>
    <build>
      ...
        <! -- you can write attributes to a file and replace them with the attributes defined in the attribute file -- >
        <filters>
            <filter>src/main/filters.properties</filter>
        </filters>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
          </resource>
        </resources>
        ...
    </build>
    ...
</project>

After compiling the packagetargetUnder the directoryjdbc.properties:

jdbc.url=jdbc:mysql://127.0.0.1:3306/dev
jdbc.username=root
jdbc.passworkd=123456

Profile introduction

What is profile?<profile>It’s like<dependencies>The same is an XML element in the POM file. In the profile, almost all the contents defined in the POM can be defined(<dependencies><properties>, plug-in configuration, etc., but it can’t define itself any more. When a profile is activated, it defines<dependencies><properties>And so on, the same content defined in the original POM will be covered, so that different configurations can be used by activating different profiles.

<! -- the perceptual knowledge of profile -- >
<project>
    ...
    <profiles>
      <profile>
        <id>dev</id>
        <properties>
            <active.profile>dev</active.profile>
            <pom.jdbc.url>jdbc:mysql://127.0.0.1:3306/dev</pom.jdbc.url>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>3.2.4.RELEASE</version>
            </dependency>
        <dependencies>
      </profile>
    </profiles>
    <dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
    </dependencies>
    ...
</project>

How to configure profile

Profiles can be configured in two places:settings.xmlandpom.xml

  • settings.xmlThe profile defined in is global and can be used for all projects. The configuration items defined in are also slightly less. Only the remote server information and attribute information can be defined(<repositories>,<pluginRepositories>, <properties>)。The information is in thepom.xmlIt can also be defined.

  • pom.xmlThe configuration that can be defined in is as follows:

  • <repositories>

  • <pluginRepositories>

  • <dependencies>

  • <plugins>

  • <properties>

  • <modules>

  • <reporting>

  • <dependencyManagement>

  • <distributionManagement>

  • And under build:

  • <defaultGoal>

  • <resources>

  • <testResources>

  • <finalName>

If the profile is activated, the configuration in the profile and the original POM will be overlapped and merged.

How to activate profile

Profile can be activated in many ways (explicit, implicit)

Explicit activation

Through Maven’s-PThe parameter activates the specified profile. The value of the parameter is the ID of the profile. Multiple profiles are separated by commas. If you do not want to activate a default profile, add one before its ID!

mvn -U clean package -Ptest,local,!ignore

In idea, you can directly check the profile you want to activate in Maven projects

Implicit activation

When configuring a profile, you can<profile>Of<activation>Element.

Default activation

  • pom.xmlIn the file

<! -- activate by default -- >
<profiles>
  <profile>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
  </profile>
</profiles>
  • settings.xmlIn the document, it was passed<activeProfiles>To configure the default active profile list

<activeProfiles>
    <activeProfile>artifactory</activeProfile>
</activeProfiles>

Activation based on operating system type

<profiles>
    <profile>
        <activation>
            <os>
                <! -- do not specify all information -- >
                <name>linux</name>
                <family>unix</family>
                <arch>amd64</arch>
                <version>3.19.0-30-generic</version>
            </os>
      </activation>
    </profile>
</profiles>

More information about OS values can be found in thehere

Activate according to JDK version

<! -- if the JDK version is 1.8, activate the profile -- >
<profiles>
  <profile>
    <activation>
      <jdk>1.8</jdk>
    </activation>
    </profile>
</profiles>

You can also pass the[1.6,1.8)Match multiple JDK versions. Please refer to the matching pattern for detailshere

Activation based on environment variables

<! -- if there is' debug 'in the environment variable and its value is' true', activate -- >
<! -- you can also not specify the '< value >' element, then only the 'debug' in the environment variable will be activated -- >
<profiles>
  <profile>
    <activation>
      <property>
        <name>debug</name>
        <value>true</value>
      </property>
    </activation>
  </profile>
</profiles>

mvn -U clean package -Ddebug=true

By judging whether the file is activated or not

<profiles>
  <profile>
    <activation>
      <file>
        <missing>/path/to/missing/file</missing>
        <exists>/path/to/exists/file</exists>
      </file>
    </activation>
    ...
  </profile>
</profiles>

Different types of implicit activation methods can be used in combination. For example, the profile can be activated according to the operating system type and JDK version specified at the same time. The profile can only be activated if both conditions match.

Filtering + Profile

Idea: configure different properties in different profiles, then activate the corresponding profile and replace it with its properties jdbc.properties A place holder in.
Continue to use the example when introducing filtering. Now add three profile configurations, which correspond to the development, test and formal environment respectively.
The modified POM file is as follows:

<project>
...
<build>
    <filters>
        <filter>src/main/filters-${active.profile}.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
                <filtering>true</filtering>
        </resource>
    </resources>
</build>
<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <active.profile>dev</active.profile>
        </properties>
        <! -- set the current profile as the default profile. Multiple profiles can be set as the default at the same time -- >
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <active.profile>test</active.profile>
        </properties>
    </profile>
    <profile>
        <id>product</id>
        <properties>
            <active.profile>product</active.profile>
        </properties>
    </profile>
...
</project>

And then in thesrc/mainNext, create three new files:filters-dev.properties,filters-test.properties,filters-product.propertiesThe contents of the document are as follows (in Chinese)filters-dev.propertiesFor example:

pom.jdbc.url=jdbc:mysql://127.0.0.1:3306/dev
pom.jdbc.username=root
pom.jdbc.password=123456

Open the contract with dev profilemvn clean package -PdevAfter packingjdbc.propertiesThe contents of the document are as follows:

jdbc.url=jdbc:mysql://127.0.0.1:3306/dev
jdbc.username=root
jdbc.password=123456

If different running environments only have different property values, use theprofile + filteringIf it is not a simple replacement (such as log4j.xml, the development environment only needs to output to the standard output, the test and online environment also needs to print to the file, and the file location and strategy are not the same), it needs to use the ant plug-in of Maven.src/main/resourcesThere are three log4j configuration files in the directory, which correspond to three running environments respectively

resources
├── log4j-product.xml

├── log4j-test.xml
└── log4j.xml

The configuration is as follows:

<profiles>
        <profile>
            <id>dev</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <build>
                <resources>
                    <resource>
                        <directory>src/main/resources</directory>
                        <excludes>
                            <exclude>config.*.properties</exclude>
                            <exclude>log4j-*.xml</exclude>
                        </excludes>
                    </resource>
                </resources>
            </build>
        </profile>
        <profile>
            <id>test</id>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-antrun-plugin</artifactId>
                        <executions>
                            <execution>
                                <phase>test</phase>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                                <configuration>
                                    <tasks>
                                        <delete file="${project.build.outputDirectory}/log4j.xml"/>
                                        <delete file="${project.build.outputDirectory}/log4j-product.xml"/>
                                        <move file="${project.build.outputDirectory}/log4j-test.xml"
                                              tofile="${project.build.outputDirectory}/log4j.xml"/>
                                    </tasks>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>product</id>
            <properties>
                <active.profile>product</active.profile>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-antrun-plugin</artifactId>
                        <executions>
                            <execution>
                                <phase>test</phase>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                                <configuration>
                                    <tasks>
                                        <delete file="${project.build.outputDirectory}/log4j.xml"/>
                                        <delete file="${project.build.outputDirectory}/log4j-test.xml"/>
                                        <move file="${project.build.outputDirectory}/log4j-product.xml"
                                              tofile="${project.build.outputDirectory}/log4j.xml"/>
                                    </tasks>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

reference resources

Recommended Today

Practice analysis of rust built-in trait: partialeq and EQ

Abstract:Rust uses traits in many places, from simple operator overloading to subtle features like send and sync. This article is shared from Huawei cloud community《Analysis of rust built-in trait: partialeq and EQ》Author: debugzhang Rust uses traits in many places, from simple operator overloading to subtle features like send and sync. Some traits can be automatically […]