Maven activating exactly one of two profiles every time

I have a maven pom.xml file which has multiple profiles:

<profiles>
  <profile>
    <id>p1</id>
  </profile>
  <profile><id>p2</id></profile>
  <profile><id>p3</id></profile>
  <profile><id>p4</id></profile>
  <profile><id>p5</id></profile>
</profiles>

I activate one or more of p1, p2, p5 some times by profile -Dp1,p5 or similar. But I want either one of p3 and p4 to be active ALWAYS. By default, it should always be p3. If I specify -Dp4, then p3 should become inactive.

Ideally, maven should throw an error if I specify -Dp3,p4 but it is not necessary.

Any idea how this can be done?

Answers


First, you don't activate a profile via -D option but via -P option via command line. Alternatively you can activate a profile via the activation element of the profile section set it as active by default or, if the profile is defined in the settings.xml via the activeProfiles section.

Maven would not throw an error if you specify profiles which are not necessary.

So, if you want to activate profile 3 by default, you can set it as following in its profile section:

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

If then you want to swith a profile on and another off, use the ! or - notation before the profile name from the command line, like for instance:

mvn clean install -Pp3!p4

It will activate the p3 profile and deactivate the p4 profile.

Note that the ! character is a special one in bash, hence you should wrap it around single quotes.

However, beware that activating a profile from command line will deactivate a profile active by default in your POM, but not a profile active by default as part of your settings.xml (which however will be shared by all of the Maven builds on that machine).

From Maven official documentation about profiles

This profile will automatically be active for all builds unless another profile in the same POM is activated using one of the previously described methods. All profiles that are active by default are automatically deactivated when a profile in the POM is activated on the command line or through its activation config.

You can play with the following POM sample about profiles activation:

<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.sample</groupId>
    <artifactId>profiles-sample</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <profiles>
        <profile>
            <id>p1</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-antrun-plugin</artifactId>
                        <version>1.5</version>
                        <executions>
                            <execution>
                                <id>p1</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                                <configuration>
                                    <target>
                                        <echo message="hello from p1" />
                                    </target>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>p2</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-antrun-plugin</artifactId>
                        <version>1.5</version>
                        <executions>
                            <execution>
                                <id>p2</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                                <configuration>
                                    <target>
                                        <echo message="hello from p2" />
                                    </target>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>p3</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-antrun-plugin</artifactId>
                        <version>1.5</version>
                        <executions>
                            <execution>
                                <id>p3</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                                <configuration>
                                    <target>
                                        <echo message="hello from p3" />
                                    </target>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

Lastly, if you don't want to set a profile activate by default but you want to enforce its usage at runtime, you can look at the Maven Enforcer Plugin and its Require Active Profile rule. Upon configuration, you can make the build fail if a required profile was not specified (hence, yes, in that case Maven will throw an error, via a plugin and not as out-of-the-box feature).


Need Your Help

Multiple dynamic method calls or declaring a variable in Grails

grails

In my view, if I have a situation where I need to use a dynamic method (such as Domain.findByName("name")) in multiple places, would it be better to define a variable with and refer to that, rathe...