【问题标题】:Activation of maven profile based on multiple properties基于多个属性激活maven配置文件
【发布时间】:2011-07-22 00:08:57
【问题描述】:

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

-Dlocation=NorthPole -Denvironment=DEV

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

<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 期望最多在那里看到一个&lt;property&gt; 元素。

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

那么有什么方法或解决方法或其他任何方法可以根据属性组合激活配置文件吗?

【问题讨论】:

  • 您正在使用 系统属性 @ 激活 Build Profiles 从命令行使用多个配置文件ID 987654328@ mvn install -Dactivationprop1 -Dactivationprop2,答案显示使用-P mvn install -P profileid1 -Pprofileid2,使用comma-delimited list form PowerShell mvn install -P "profile-1,profile-2"

标签: maven-2 profile activation


【解决方案1】:

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

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

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

【讨论】:

  • 你是对的,事实证明,直接使用配置文件并在其中设置属性(就像通过命令行设置一样)将是这里的最佳选择。无论如何感谢您的回答!
  • 例子可能不错... :)
【解决方案2】:

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

<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 ...

【讨论】:

  • 当然,但是如果我有配置文件 NorthPole-DEV.xml 和 NorthPole-PROD 我怎么知道在你的场景中使用哪一个?我需要根据位置和环境做出决定并采取行动
  • 自从我将 ANT 构建转换为 maven 后,我可能过于拘泥于使用命令行属性。事实证明,最好通过配置文件来完成,在其中设置所需的属性并完全忘记这些属性。抱歉误导性问题。将此标记为正确答案。
  • 如果两个配置文件为同一属性定义不同的值,您能否澄清一下应该发生什么?哪个被拍了?
  • 这并不能解决问题,因为第二个属性将触发配置文件,即使认为第一个没有设置(在我的情况下很重要)。 -1 代表典型的无用 Maven 建议(例如,“以 Maven 方式去做,让一切变得愚蠢、臃肿且无法维护”)。
  • @worky 如果您认为这是无用的,那么您应该以您认为会更好的方式改进 maven。
【解决方案3】:

可能的解决方案

试试这个扩展: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 &amp;&amp; location=="NorthPole" &amp;&amp; 
                   isdef environment &amp;&amp; environment=="DEV"</value>
        </property>
    </activation>
</profile>

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

如何避免手动配置Maven

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

  • 您可以添加 $MAVEN_HOME/lib/ext/el-profile-activator-extension.jar 文件的 activated on absense 配置文件
  • 此配置文件可以在初始化阶段使用 dependency plugin 从 maven 下载 jar 到 $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>

【讨论】:

    【解决方案4】:

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

    我不得不发布另一个回复,因为我无法将 cmets 添加到其他人的回复中。 :(

    【讨论】:

    • 好吧,您可以将其添加到您的第一个答案中:-)
    【解决方案5】:

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

    <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' 中添加

    【讨论】:

    • 嗯,但这是针对只有北极的情况。在这种情况下,我根本不需要它的财产。正确的? :) 问题中还描述了其他位置。
    • 是的,您可以根据需要添加其他配置文件。基本上,位置和环境属性是根据所选配置文件设置的,因此您不需要单独的属性文件。
    【解决方案6】:

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

    以下是链接:

    Youtube:https://youtu.be/UbDpvh3YvDw

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

    代码sn-p:

    应用参数

    custom.server_url = @custom.server_url@

    custom.server_port = @custom.server_port@

    custom.debuggable = @custom.debuggable@

    custom.image_quality = 高

    覆盖参数

    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>
    

    让我知道它是否有效!问候!

    【讨论】:

    • Op 的问题与 spring-boot 无关
    猜你喜欢
    • 2011-11-11
    • 2012-02-17
    • 1970-01-01
    • 2010-12-03
    • 2017-10-11
    • 2013-09-24
    • 1970-01-01
    • 2011-06-05
    • 2014-10-29
    相关资源
    最近更新 更多