Activation of maven profile based on multiple properties
Solution 1
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 ...
Solution 2
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.
Solution 3
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>
Solution 4
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. :(
Comments
-
Jan Zyka about 4 years
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
locationEnv
of valueNorthPole-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?
-
Jan Zyka over 13 yearsHm, but this is for the case there is North Pole only. In such case I wouldn't need a property for it at all. right? :) There are other locations as well sa described in the question.
-
Prabhjot over 13 yearsYes, you can add other profiles as per your requirement.Essentially, location and env properties are being set as per the profile selected, thus you won't need a separate properties file.
-
Jan Zyka over 13 yearsSure but if I have config file NorthPole-DEV.xml and NorthPole-PROD how would I know which one to use in your scenario? I need to decide based on both location and environment and act upon them
-
Sean Patrick Floyd over 13 yearswell, you could have added this to your first answer instead :-)
-
Jan Zyka over 13 yearsSince I was converting the ANT build into maven I probably was too fixed on using commandline properties. It turned out that it is really better to do it via profiles, set required properties in them and forget the properties at all. Sorry for missleading question. Marking this as correct answer.
-
Jan Zyka over 13 yearsYou are right, it turned out that going directly with profiles and set the properties in them (just as if they were set via commandline) will be the best option here. Thanks for answer anyway!
-
Ivaylo Slavov about 12 yearsCould you clarify what should be expected if the 2 profiles define different values for the same property? Which one is taken?
-
woky almost 12 yearsThat does not solve the problem because second property will trigger the profile even thought first is not set (it matters in my case). -1 for typical useless Maven advice (eg. "do it Maven way and make everything dumb, bloated & unmaintainable").
-
khmarbaise over 7 years@worky If you are the opinion is is useless than you should improve maven in a way you think it would be better.
-
rogerdpack about 6 yearsexample might be nice... :)
-
Zack almost 6 yearsOp's question is not spring-boot related