基于多个属性激活maven profile

发布于 2024-10-25 08:19:36 字数 973 浏览 10 评论 0原文

我正在为一个项目创建一个 Maven 2 构建,并且我想出了配置文件,因为必须为不同的位置(例如柏林、巴黎、北极)和不同的环境(开发、生产)创建构建。这些是通过属性指定的。因此,对于“North Pole”“DEV”,我这样做:

-Dlocation=NorthPole -Denvironment=DEV

现在我想根据这两个属性(而不仅仅是一个)来激活我的个人资料。所以我尝试了以下操作:

<profiles>
  <profile>
    <id>NOrth Pole DEV</id>
    <activation>
      <property>
        <name>location</name>
        <value>NorthPole</value>
      </property>
      <property>
        <name>environment</name>
        <value>DEV</value>
      </property>
    </activation>
    ... <!-- Set some North Pole DEV specific stuff -->
  </profile>
</profiles>

这不起作用,maven 期望在那里看到最多一个 元素。

请注意,我对这些属性还有其他用途,因此将其设为值 NorthPole-DEV 的单一属性 locationEnv 并不是我想要的。

那么有没有什么方法或解决方法或其他任何方式来激活基于属性组合的配置文件?

I am creating a maven 2 build for a project and I came up with profiles since the build has to be created for both different locations (say Berlin, Paris, North Pole) and different environment (Development, Production). Those are specified via properties. So for "North Pole" "DEV" I do:

-Dlocation=NorthPole -Denvironment=DEV

Now I would like to acivate my porfile based on both these properties, not just one. So I tried following:

<profiles>
  <profile>
    <id>NOrth Pole DEV</id>
    <activation>
      <property>
        <name>location</name>
        <value>NorthPole</value>
      </property>
      <property>
        <name>environment</name>
        <value>DEV</value>
      </property>
    </activation>
    ... <!-- Set some North Pole DEV specific stuff -->
  </profile>
</profiles>

This doesn't work, maven expect to see at most one <property> element there.

Please note I have another use for the properties as well so making it single property locationEnvof value NorthPole-DEV isn't what I want to have.

So is there any way or workaround or whatever else how to activate an profile based on combination of properties?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

瀞厅☆埖开 2024-11-01 08:19:36

恐怕没有好的解决方案可以解决您的问题(除非有我不知道的新 Maven 功能)。

理论上,您可以引入一个派生属性,其值由您列出的两个属性连接而成。然而,问题是配置文件是在 pom 中定义的属性之前评估的,因此这样的派生属性不能用于激活配置文件:-(

对于类似问题,我能想到的最佳解决方法是显式激活配置文件,并将命令行参数的不同组合放入单独的批处理/脚本文件中,以使执行更简单并避免输入错误问题。

I am afraid there is no good solution to your problem (unless there are new Maven features I am not aware of).

In theory, you could introduce a derived property whose value is concatenated from the two properties you listed. However, the problem is that profiles are evaluated before properties defined in the pom, so such a derived property can't be used to activate a profile :-(

The best workaround I could think of for a similar problem was to activate the profile explicitly, and put the different combinations of command line parameters into separate batch/script files to make execution simpler and avoid mistyping issues.

梦明 2024-11-01 08:19:36

为什么不直接使用配置文件,例如:

<profiles>
   <profile>
    <id>north-pole</id>
    <activation>
      <activeByDefault>false</activeByDefault>
    </activation>
    ....
  </profile>
   <profile>
    <id>dev</id>
    <activation>
      <activeByDefault>false</activeByDefault>
    </activation>
    ....
  </profile>
</profiles>

现在您可以通过命令行激活配置文件。

mvn -Pdev,north-pole ...

why not using profile directly like:

<profiles>
   <profile>
    <id>north-pole</id>
    <activation>
      <activeByDefault>false</activeByDefault>
    </activation>
    ....
  </profile>
   <profile>
    <id>dev</id>
    <activation>
      <activeByDefault>false</activeByDefault>
    </activation>
    ....
  </profile>
</profiles>

Now you can activate the profiles by command line.

mvn -Pdev,north-pole ...
岁吢 2024-11-01 08:19:36

可能的解决方案

尝试此扩展: https://github.com/kpiwko/el-profile-activator -extension

这允许有这样的语法:

<profile>
    <id>NOrth Pole DEV</id>

    <activation>
        <property>
            <!-- mvel property name is obligatory -->
            <name>mvel</name>
            <value>isdef location && location=="NorthPole" && 
                   isdef environment && environment=="DEV"</value>
        </property>
    </activation>
</profile>

我自己没有尝试过,但似乎是一个不错的项目。

如何避免手动配置Maven

您需要将项目所需的两个jar放入$MAVEN_HOME/lib/ext中。不过,您可以自动配置它们。像这样:

  • 您可以添加一个在缺席时激活的配置文件$MAVEN_HOME/lib/ext/el-profile-activator-extension.jar 文件
  • 此配置文件可以使用 依赖插件 到 init 阶段的 $MAVEN_HOME/lib/ext 文件夹中
  • 然后你可以写出一条消息,构建配置了 maven 文件夹,并且下次构建将会成功。

测试简介:

<profile>
    <id>prepare-maven-extended-libs</id>
    <activation>
      <file>
        <missing>${maven.home}/lib/ext/el-profile-activator-extension.jar</missing>
      </file>
    </activation>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.8</version>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.redhat.jboss.maven</groupId>
                                    <artifactId>el-profile-activator-extension</artifactId>
                                    <version>1.0.0-SNAPSHOT</version>
                                    <type>jar</type>
                                    <overWrite>true</overWrite>
                                    <outputDirectory>${maven.home}/lib/ext</outputDirectory>
                                    <destFileName>el-profile-activator-extension.jar</destFileName>
                                </artifactItem>
                                <artifactItem>
                                    <groupId>org.mvel</groupId>
                                    <artifactId>mvel2</artifactId>
                                    <version>2.1.3.Final</version>
                                    <type>jar</type>
                                    <overWrite>true</overWrite>
                                    <outputDirectory>${maven.home}/lib/ext</outputDirectory>
                                    <destFileName>mvel2.jar</destFileName>
                                </artifactItem>
                            </artifactItems>
                            <outputDirectory>${project.build.directory}/wars</outputDirectory>
                            <overWriteReleases>true</overWriteReleases>
                            <overWriteSnapshots>true</overWriteSnapshots>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.gmaven</groupId>
                <artifactId>gmaven-plugin</artifactId>
                <version>1.4</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals><goal>execute</goal></goals>
                    </execution>
                </executions>
                <configuration>
                    <source>
                        fail("For profile activation we use an extension jar. It is now in your ${maven.home}/lib/ext folder. Please restart the build, and then it will be successful.")
                    </source>
                </configuration>
            </plugin>               
        </plugins>
    </build>
</profile>

Possible Solution

Try this extension: https://github.com/kpiwko/el-profile-activator-extension

This allows to have such syntax:

<profile>
    <id>NOrth Pole DEV</id>

    <activation>
        <property>
            <!-- mvel property name is obligatory -->
            <name>mvel</name>
            <value>isdef location && location=="NorthPole" && 
                   isdef environment && environment=="DEV"</value>
        </property>
    </activation>
</profile>

I did not try it myself, but seems to be a nice project.

How to avoid manual configuration of Maven

You need to put the needed two jars of the project into $MAVEN_HOME/lib/ext. You can however automize configuring them. Like this:

  • You can add a profile which is activated on absense of $MAVEN_HOME/lib/ext/el-profile-activator-extension.jar file
  • This profile can download the jars from maven using dependency plugin into the $MAVEN_HOME/lib/ext folder in init phase
  • Then you can write out a message, that the build configured the maven folder, and the next build will be successful.

Tested profile:

<profile>
    <id>prepare-maven-extended-libs</id>
    <activation>
      <file>
        <missing>${maven.home}/lib/ext/el-profile-activator-extension.jar</missing>
      </file>
    </activation>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.8</version>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>com.redhat.jboss.maven</groupId>
                                    <artifactId>el-profile-activator-extension</artifactId>
                                    <version>1.0.0-SNAPSHOT</version>
                                    <type>jar</type>
                                    <overWrite>true</overWrite>
                                    <outputDirectory>${maven.home}/lib/ext</outputDirectory>
                                    <destFileName>el-profile-activator-extension.jar</destFileName>
                                </artifactItem>
                                <artifactItem>
                                    <groupId>org.mvel</groupId>
                                    <artifactId>mvel2</artifactId>
                                    <version>2.1.3.Final</version>
                                    <type>jar</type>
                                    <overWrite>true</overWrite>
                                    <outputDirectory>${maven.home}/lib/ext</outputDirectory>
                                    <destFileName>mvel2.jar</destFileName>
                                </artifactItem>
                            </artifactItems>
                            <outputDirectory>${project.build.directory}/wars</outputDirectory>
                            <overWriteReleases>true</overWriteReleases>
                            <overWriteSnapshots>true</overWriteSnapshots>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.gmaven</groupId>
                <artifactId>gmaven-plugin</artifactId>
                <version>1.4</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals><goal>execute</goal></goals>
                    </execution>
                </executions>
                <configuration>
                    <source>
                        fail("For profile activation we use an extension jar. It is now in your ${maven.home}/lib/ext folder. Please restart the build, and then it will be successful.")
                    </source>
                </configuration>
            </plugin>               
        </plugins>
    </build>
</profile>
江心雾 2024-11-01 08:19:36

khmarbaise 的答案对我来说似乎更优雅。
对于 Jan 的评论,您可以通过附加属性来引用该文件
例如,使用配置文件 dev,激活 North Pole,您可以参考 NorthPole-dev.xml
${location}-${env}.xml。

我不得不发表另一条回复,因为我无法向其他人的回复添加评论。 :(

khmarbaise's answer seems more elegant to me.
To Jan's comment, you can refer to the file by appending the properites
e.g. with profile dev, North Pole activated you can refer to NorthPole-dev.xml with
${location}-${env}.xml.

I had to post another reply as I'm not able to add comments to other's replies. :(

伴我心暖 2024-11-01 08:19:36

我相信你可以做这样的事情

<properties>
        <env>dev</env>
        <location>North Pole</location>
    </properties>

<profiles>
        <!-- dev North Profile -->
        <profile>
            <id>dev North Pole</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <!-- qa North Profile -->
        <profile>
            <id>qa North Pole</id>
            <properties>
                         <env>qa</env>
                             <location>North Pole</location>
            </properties>
        </profile>

    </profiles>
<build>
do profile specific stuff here
</build>

当然,要激活配置文件,你可以在命令“-P=dev North Pole”中添加

I believe you can do something like this

<properties>
        <env>dev</env>
        <location>North Pole</location>
    </properties>

<profiles>
        <!-- dev North Profile -->
        <profile>
            <id>dev North Pole</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <!-- qa North Profile -->
        <profile>
            <id>qa North Pole</id>
            <properties>
                         <env>qa</env>
                             <location>North Pole</location>
            </properties>
        </profile>

    </profiles>
<build>
do profile specific stuff here
</build>

Of couse, to activate a profile you can add in the command '-P=dev North Pole'

∞觅青森が 2024-11-01 08:19:36

经过详尽的调查后,我发布了一个视频,其中解释了 Spring Boot 中每个环境的 Maven 配置文件的使用情况。这是一个 Spring Boot Rest 项目,它使用 Maven 配置文件处理每个环境的应用程序属性。

以下是链接:

YouTube:https://youtu.be/UbDpvh3YvDw

Github:https://github.com/carlosCharz/mavenprofilespringboot

代码片段:

应用程序参数

custom.server_url = @custom.server_url@

custom.server_port = @custom.server_port@

custom.debuggable = @custom.debuggable@

custom.image_quality = HIGH

覆盖参数

custom.server_url = api-dev.yourserver.com

custom.server_port = 80

custom.debuggable = true

<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.wedevol</groupId>
<artifactId>mvnspringboot</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>Spring Boot Project with Maven</name>
<description>This is a spring boot rest project that handle the application properties per environment using Maven profiles.</description>

<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
    <!-- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes -->
</parent>

<dependencies>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>

<!-- Maven profile per environment -->
<profiles>
    <profile>
        <id>local</id>
        <activation>
           <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <overrides.props.file>local.overrides.properties</overrides.props.file>
            <current.profile>local</current.profile>
        </properties>
    </profile>
    <profile>
        <id>dev</id>
        <properties>
            <overrides.props.file>dev.overrides.properties</overrides.props.file>
            <current.profile>dev</current.profile>
        </properties>
    </profile>
    <profile>
        <id>qa</id>
        <properties>
            <overrides.props.file>qa.overrides.properties</overrides.props.file>
            <current.profile>qa</current.profile>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <overrides.props.file>prod.overrides.properties</overrides.props.file>
            <current.profile>prod</current.profile>
        </properties>
    </profile>
</profiles>

<build>
    <finalName>mvnspringboot</finalName>
    <!-- Maven Resources. It handles the copying of project resources to the output directory. -->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>profiles/*</exclude>
            </excludes>
        </resource>
    </resources>
    <!-- Maven filtering. The variables are included in the resources ( ${..} or @...@ delimiters) -->
    <filters>
        <filter>src/main/resources/profiles/${overrides.props.file}</filter>
    </filters>
    <plugins>
        <!-- Spring boot maven plugin -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <!-- Ant plugin to print the current maven profile -->
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <tasks>
                            <echo>Current maven active profile: ${current.profile}</echo>
                        </tasks>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

让我知道如果有效的话!问候!

After an exhaustive investigation I've posted a video where I explain the usage of Maven profiles per environment with Spring Boot. That is a spring boot rest project that handle the application properties per environment using Maven profiles.

Here are the links:

Youtube: https://youtu.be/UbDpvh3YvDw

Github: https://github.com/carlosCharz/mavenprofilespringboot

Code snippet:

Application parameters

custom.server_url = @custom.server_url@

custom.server_port = @custom.server_port@

custom.debuggable = @custom.debuggable@

custom.image_quality = HIGH

Overrides parameters

custom.server_url = api-dev.yourserver.com

custom.server_port = 80

custom.debuggable = true

<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.wedevol</groupId>
<artifactId>mvnspringboot</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>Spring Boot Project with Maven</name>
<description>This is a spring boot rest project that handle the application properties per environment using Maven profiles.</description>

<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
    <!-- https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes -->
</parent>

<dependencies>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>

<!-- Maven profile per environment -->
<profiles>
    <profile>
        <id>local</id>
        <activation>
           <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <overrides.props.file>local.overrides.properties</overrides.props.file>
            <current.profile>local</current.profile>
        </properties>
    </profile>
    <profile>
        <id>dev</id>
        <properties>
            <overrides.props.file>dev.overrides.properties</overrides.props.file>
            <current.profile>dev</current.profile>
        </properties>
    </profile>
    <profile>
        <id>qa</id>
        <properties>
            <overrides.props.file>qa.overrides.properties</overrides.props.file>
            <current.profile>qa</current.profile>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <overrides.props.file>prod.overrides.properties</overrides.props.file>
            <current.profile>prod</current.profile>
        </properties>
    </profile>
</profiles>

<build>
    <finalName>mvnspringboot</finalName>
    <!-- Maven Resources. It handles the copying of project resources to the output directory. -->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>profiles/*</exclude>
            </excludes>
        </resource>
    </resources>
    <!-- Maven filtering. The variables are included in the resources ( ${..} or @...@ delimiters) -->
    <filters>
        <filter>src/main/resources/profiles/${overrides.props.file}</filter>
    </filters>
    <plugins>
        <!-- Spring boot maven plugin -->
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <!-- Ant plugin to print the current maven profile -->
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <tasks>
                            <echo>Current maven active profile: ${current.profile}</echo>
                        </tasks>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Let me know if it worked! Gretings!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文