Maven Plugin Configuration - The (Unknown) Tiny Details

Overview

If you are using Apache Maven I suppose you have configured several plugins within your pom file already. As an example we use the Maven Enforcer Plugin to prevent starting a given build with a Maven version which is less than 3.5.0 which looks like this:

 1<project>
 2  <build>
 3    <plugins>
 4      <plugin>
 5        <groupId>org.apache.maven.plugins</groupId>
 6        <artifactId>maven-enforcer-plugin</artifactId>
 7        <version>3.0.0-M3</version>
 8        <executions>
 9          <execution>
10            <id>id-enforce</id>
11            <goals>
12              <goal>enforce</goal>
13            </goals>
14            <configuration>
15              <rules>
16                <requireMavenVersion>
17                  <version>3.5.0</version>
18                </requireMavenVersion>
19              </rules>
20            </configuration>
21          </execution>
22        </executions>
23      </plugin>
24    </plugins>
25  </build>
26</project>

Now you are calling Maven like this: mvn enforcer:enforce but now you are astonished about the failure which you will be faced with (for brevity inserted some line breaks into the output):

 1$ mvn enforcer:enforce 
 2[INFO] Scanning for projects...
 3[INFO] 
 4[INFO] -------------< com.soebes.articles.plugins:configuration >--------------
 5[INFO] Building configuration 1.0-SNAPSHOT
 6[INFO] --------------------------------[ jar ]---------------------------------
 7[INFO] 
 8[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ configuration ---
 9[INFO] ------------------------------------------------------------------------
10[INFO] BUILD FAILURE
11[INFO] ------------------------------------------------------------------------
12[INFO] Total time:  0.363 s
13[INFO] Finished at: 2021-03-22T20:01:53+01:00
14[INFO] ------------------------------------------------------------------------
15[ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce (default-cli)
16on project configuration: No rules are configured. Use the skip flag if you want to disable execution. -> [Help 1]
17[ERROR] 
18[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
19[ERROR] Re-run Maven using the -X switch to enable full debug logging.
20[ERROR] 
21[ERROR] For more information about the errors and possible solutions, please read the following articles:
22[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

That looks like the configuration we have given in the example is not taken into account. What should I say. Yes that is exactly the point. Now the crucial question is: Why?

Details

Let's dive more into details why this happens. The reason is that by calling Maven via mvn enforcer:enforce you have not started a life cycle (something like clean, package or alike). You have requested to execute the goal enforce of the Maven Enforcer Plugin.

This means in the end there is a difference for configuring plugins between calling a life cycle and a goal.

How can we check that what I have claimed is correct? That's easy to accomplish by just calling a life cycle phase like initialize (you can also use verify or package instead of initialize only takes longer to run.):

 1$ mvn initialize 
 2[INFO] Scanning for projects...
 3[INFO] 
 4[INFO] -------------< com.soebes.articles.plugins:configuration >--------------
 5[INFO] Building configuration 1.0-SNAPSHOT
 6[INFO] --------------------------------[ jar ]---------------------------------
 7[INFO] 
 8[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (id-enforce) @ configuration ---
 9[INFO] ------------------------------------------------------------------------
10[INFO] BUILD SUCCESS
11[INFO] ------------------------------------------------------------------------
12[INFO] Total time:  0.355 s
13[INFO] Finished at: 2021-03-22T20:02:40+01:00
14[INFO] ------------------------------------------------------------------------

So first mission accomplished and proved that the previously given configuration is now taken into account.

So based on those insights can we somehow create a configuration which is taken into account while calling a goal enforcer:enforce ? Yes there is a way to do so via the following configuration:

 1<project>
 2  <build>
 3    <plugins>
 4      <plugin>
 5        <groupId>org.apache.maven.plugins</groupId>
 6        <artifactId>maven-enforcer-plugin</artifactId>
 7        <version>3.0.0-M3</version>
 8        <executions>
 9          <execution>
10            <id>default-cli</id>
11            <goals>
12              <goal>enforce</goal>
13            </goals>
14            <configuration>
15              <rules>
16                <requireMavenVersion>
17                  <version>3.5.0</version>
18                </requireMavenVersion>
19              </rules>
20            </configuration>
21          </execution>
22        </executions>
23      </plugin>
24    </plugins>
25  </build>
26</project>

Now we are calling the goal:

 1$ mvn enforcer:enforce 
 2[INFO] Scanning for projects...
 3[INFO] 
 4[INFO] -------------< com.soebes.articles.plugins:configuration >--------------
 5[INFO] Building configuration 1.0-SNAPSHOT
 6[INFO] --------------------------------[ jar ]---------------------------------
 7[INFO] 
 8[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ configuration ---
 9[INFO] ------------------------------------------------------------------------
10[INFO] BUILD SUCCESS
11[INFO] ------------------------------------------------------------------------
12[INFO] Total time:  0.516 s
13[INFO] Finished at: 2021-03-22T20:29:34+01:00
14[INFO] ------------------------------------------------------------------------

You can also call the life cycle like this:

 1$ mvn initialize 
 2[INFO] Scanning for projects...
 3[INFO] 
 4[INFO] -------------< com.soebes.articles.plugins:configuration >--------------
 5[INFO] Building configuration 1.0-SNAPSHOT
 6[INFO] --------------------------------[ jar ]---------------------------------
 7[INFO] 
 8[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ configuration ---
 9[INFO] ------------------------------------------------------------------------
10[INFO] BUILD SUCCESS
11[INFO] ------------------------------------------------------------------------
12[INFO] Total time:  0.498 s
13[INFO] Finished at: 2021-03-27T16:18:03+01:00
14[INFO] ------------------------------------------------------------------------

Have you spotted the difference? The only difference was between <id>id-enforce</id> (of the first configuration example) and <id>default-cli</id> in the second one. The name default-cli is, as the name implies, the default used for command line execution. This means you can define configuration/execution which are only used for calling goals from command line and not part of the life cycle.

In the next step we would like to make configurations where one is applied for command line execution <id>default-cli</id> and another for life cycle execution <id>another-id</id>.

 1<project>
 2  <build>
 3    <plugins>
 4      <plugin>
 5        <groupId>org.apache.maven.plugins</groupId>
 6        <artifactId>maven-enforcer-plugin</artifactId>
 7        <version>3.0.0-M3</version>
 8        <executions>
 9          <execution>
10            <id>default-cli</id>
11            <goals>
12              <goal>enforce</goal>
13            </goals>
14            <configuration>
15              <rules>
16                <requireJavaVersion>
17                  <version>25</version>
18                </requireJavaVersion>
19              </rules>
20            </configuration>
21          </execution>
22          <execution>
23            <id>another-id</id>
24            <goals>
25              <goal>enforce</goal>
26            </goals>
27            <configuration>
28              <rules>
29                <requireMavenVersion>
30                  <version>3.9.0</version>
31                </requireMavenVersion>
32              </rules>
33            </configuration>
34          </execution>
35        </executions>
36      </plugin>
37    </plugins>
38  </build>
39</project>

The above configuration requires a JDK version 25 being used for building instead of the one I'm currently using (Just for demonstration purposes; Ok maybe a bit in the future). The second configuration checks for the Maven version which is expected to be used for that build. So let use call the goal first:

 1$ mvn enforcer:enforce 
 2[INFO] Scanning for projects...
 3[INFO] 
 4[INFO] -------------< com.soebes.articles.plugins:configuration >--------------
 5[INFO] Building configuration 1.0-SNAPSHOT
 6[INFO] --------------------------------[ jar ]---------------------------------
 7[INFO] 
 8[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ configuration ---
 9[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message:
10Detected JDK Version: 11.0.9 is not in the allowed range 25.
11[INFO] ------------------------------------------------------------------------
12[INFO] BUILD FAILURE
13[INFO] ------------------------------------------------------------------------
14[INFO] Total time:  0.549 s
15[INFO] Finished at: 2021-03-22T20:45:27+01:00
16[INFO] ------------------------------------------------------------------------
17[ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce (default-cli)
18 on project configuration: Some Enforcer rules have failed. Look above for specific messages explaining 
19 why the rule failed. -> [Help 1]
20[ERROR] 
21[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
22[ERROR] Re-run Maven using the -X switch to enable full debug logging.
23[ERROR] 
24[ERROR] For more information about the errors and possible solutions, please read the following articles:
25[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

You can see the command line only configuration is taken into account which can be identified by the message Detected JDK Version: 11.0.9 is not in the allowed range 25.. So worked as expected. Now we try to execute within life cycle:

 1$ mvn initialize 
 2[INFO] Scanning for projects...
 3[INFO] 
 4[INFO] -------------< com.soebes.articles.plugins:configuration >--------------
 5[INFO] Building configuration 1.0-SNAPSHOT
 6[INFO] --------------------------------[ jar ]---------------------------------
 7[INFO] 
 8[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ configuration ---
 9[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireJavaVersion failed with message:
10Detected JDK Version: 11.0.9 is not in the allowed range 25.
11[INFO] ------------------------------------------------------------------------
12[INFO] BUILD FAILURE
13[INFO] ------------------------------------------------------------------------
14[INFO] Total time:  0.450 s
15[INFO] Finished at: 2021-03-27T16:40:31+01:00
16[INFO] ------------------------------------------------------------------------
17[ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) 
18on project configuration: Some Enforcer rules have failed. Look above for specific messages explaining 
19why the rule failed. -> [Help 1]
20[ERROR] 
21[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
22[ERROR] Re-run Maven using the -X switch to enable full debug logging.
23[ERROR] 
24[ERROR] For more information about the errors and possible solutions, please read the following articles:
25[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

This hasn't been expected? What went wrong? The problem is simply related to the plugin or more accurate to the enforce goal which has a default binding to the life cycle which can be identified by reading the doc of the plugin (excerpt of it):

 1enforcer:enforce
 2Full name:
 3  org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce
 4
 5Description:
 6  This goal executes the defined enforcer-rules once per module.
 7  Attributes:
 8
 9* Requires a Maven project to be executed.
10* Binds by default to the lifecycle phase: validate.

The important part is the last line: Binds by default to the lifecycle phase: validate.. This describes the behaviour we can observe here. We are using the goal enforce simply by defining the goal. If you bind a plugin like the following:

 1<project>
 2.....
 3        <executions>
 4          <execution>
 5            <id>default-cli</id>
 6            <goals>
 7              <goal>enforce</goal>
 8            </goals>
 9            <configuration>
10              <rules>
11                <requireJavaVersion>
12                  <version>25</version>
13                </requireJavaVersion>
14              </rules>
15            </configuration>
16          </execution>
17          <execution>
18            <id>another-id</id>
19            <goals>
20              <goal>enforce</goal>
21            </goals>
22            <configuration>
23              <rules>
24                <requireMavenVersion>
25                  <version>3.9.0</version>
26                </requireMavenVersion>
27              </rules>
28            </configuration>
29          </execution>
30        </executions>
31  ...
32</project>

This implies that the life cycle phase to which the plugin is bound is done by the plugin itself. That means in the end the final configuration it looks like this:

 1<project>
 2.....
 3        <executions>
 4          <execution>
 5            <id>default-cli</id>
 6            <goals>
 7              <goal>enforce</goal>
 8            </goals>
 9            <phase>initialize</phase>
10            <configuration>
11              <rules>
12                <requireJavaVersion>
13                  <version>25</version>
14                </requireJavaVersion>
15              </rules>
16            </configuration>
17          </execution>
18          <execution>
19            <id>another-id</id>
20            <goals>
21              <goal>enforce</goal>
22            </goals>
23            <phase>initialize</phase>
24            <configuration>
25              <rules>
26                <requireMavenVersion>
27                  <version>3.9.0</version>
28                </requireMavenVersion>
29              </rules>
30            </configuration>
31          </execution>
32        </executions>
33  ...
34</project>

This means by calling the life cycle mvn initialize both executions will be executed and in the end also the first one (for java version) is executed even by giving a <id>default-cli</id>.

Life Cycle Binding

In cases where you want to make clear in which life cycle phase a plugin is bound just write it into the configuration. That makes it possible to override the defaults which a plugin (better the plugin author(s)) has defined. We can use this information to solve our problem by changing the configuration via the following approach: We simply decouple the enforce goal for one execution from the life cycle by defining a life cycle phase (UNKNOWN) which simply does not exist.

 1<project>
 2  <build>
 3    <plugins>
 4      <plugin>
 5        <groupId>org.apache.maven.plugins</groupId>
 6        <artifactId>maven-enforcer-plugin</artifactId>
 7        <version>3.0.0-M3</version>
 8        <executions>
 9          <execution>
10            <id>default-cli</id>
11            <goals>
12              <goal>enforce</goal>
13            </goals>
14            <phase>UNKNOWN</phase>
15            <configuration>
16              <rules>
17                <requireJavaVersion>
18                  <version>25</version>
19                </requireJavaVersion>
20              </rules>
21            </configuration>
22          </execution>
23          <execution>
24            <id>another-id</id>
25            <goals>
26              <goal>enforce</goal>
27            </goals>
28            <configuration>
29              <rules>
30                <requireMavenVersion>
31                  <version>3.9.0</version>
32                </requireMavenVersion>
33              </rules>
34            </configuration>
35          </execution>
36        </executions>
37      </plugin>
38    </plugins>
39  </build>
40</project>

The other configuration <id>another-id</id> can be keep unchanged. This (intended) coupling could have been identified in earlier outputs where a line was printed out:

1$ mvn initialize
2...
3[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ configuration ---
4..

This indicates that the goal enforce of the plugin is bound to a default life cycle initialize by the plugin itself in contradiction to the output (default-cli) (which might brought us to the wrong path).

This is a strong indicator that the given goal (enforce) is not intended to be called from command line. I generally recommend not to try to configure/execute goals on command line while the docs shows: Binds by default to the lifecycle phase: ... There are most likely exceptions but in general do not try it otherwise you would enter the dark side of the force ;-)

There are also examples like Maven Assembly Plugin which has exactly one goal single which is not bound to a life cycle phase at all. This does not mean to use the single goal via command line (technically you can) but usually it does not make sense. Generally it makes sense to bind the single goal to a life cycle phase via the appropriate configuration. Based on different project setups it could make sense to bind it to prepare-package or to the package phase instead. This is exactly the reason that the plugin is not bound to any phase by default otherwise it would be necessary to decouple it from one of the phases if you are using the other one.

Goals For Command Line

Let us take a look to a plugin which is used from the command more or less exclusively. The Versions Maven Plugin has a lot of goals which are all intended for calling via command line and not within the life cycle.

Take a look at a typical example how the Versions Maven Plugin is used. We have a project where we would like to change the version number. That can easily being done by using the following call:

1$ mvn versions:set -DnewVersion=1.2.0 -DgenerateBackupPoms=false
2...

So the plugin will change the versions in the pom.xml file. You have to remember the option -DgenerateBackupPoms=false everytime you are calling it otherwise there will backups being created of the original pom.xml files (pom.xml.versionsBackup). Afterwards you have either delete those files manually or with the help of your version control but this situation can be improved by using the configuration for the command line only. The configuration looks like the following:

 1<project>
 2  <build>
 3    <pluginManagement>
 4      <plugins>
 5        <plugin>
 6          <groupId>org.codehaus.mojo</groupId>
 7          <artifactId>versions-maven-plugin</artifactId>
 8          <version>2.8.1</version>
 9          <executions>
10            <execution>
11              <id>default-cli</id>
12              <configuration>
13                <generateBackupPoms>false</generateBackupPoms>
14              </configuration>
15            </execution>
16          </executions>
17        </plugin>
18        ...
19      </plugins>
20    </pluginManagement>
21  </build>
22</project>

Now you can make a simpler call like this:

 1$ mvn versions:set -DnewVersion=2.0.0-SNAPSHOT
 2[INFO] Scanning for projects...
 3[INFO] 
 4[INFO] -------------< com.soebes.articles.plugins:configuration >--------------
 5[INFO] Building configuration 1.0.0-SNAPSHOT
 6[INFO] --------------------------------[ jar ]---------------------------------
 7[INFO] 
 8[INFO] --- versions-maven-plugin:2.8.1:set (default-cli) @ configuration ---
 9[INFO] Local aggregation root: /.../configuration
10[INFO] Processing change of com.soebes.articles.plugins:configuration:1.0.0-SNAPSHOT -> 2.0.0-SNAPSHOT
11[INFO] Processing com.soebes.articles.plugins:configuration
12[INFO]     Updating project com.soebes.articles.plugins:configuration
13[INFO]         from version 1.0.0-SNAPSHOT to 2.0.0-SNAPSHOT
14[INFO] 
15[INFO] ------------------------------------------------------------------------
16[INFO] BUILD SUCCESS
17[INFO] ------------------------------------------------------------------------
18[INFO] Total time:  0.853 s
19[INFO] Finished at: 2021-03-28T20:32:58+02:00
20[INFO] ------------------------------------------------------------------------

Configuration for different Command Line Invocation

We have reached an interesting level of configuration options for Maven plugins, unfortunately there is a limitation. You can configure exactly one command line call (<id>default-cli</id>). If you want to make different configuration for different CLI calls it is simply not possible that way.

Starting with Maven 3.3.1+ (in the meantime 5 years ago) there had been an interesting enhancement for goal invocation.

Let us begin with the default-cli based on previous examples (using exec-maven-plugin here):

 1<project...>
 2 
 3  <build>
 4    <plugins>
 5      <plugin>
 6        <groupId>org.codehaus.mojo</groupId>
 7        <artifactId>exec-maven-plugin</artifactId>
 8        <version>3.0.0</version>
 9        <executions>
10          <execution>
11            <id>default-cli</id>
12            <configuration>
13              <mainClass>com.soebes.test.First</mainClass>
14            </configuration>
15          </execution>
16        </executions>
17      </plugin>
18    </plugins> 
19  </build>
20</project>

As described in detail in previous parts you can now call Maven like this:

1$ mvn exec:java
2...

That will use the above configuration. So now we enhance the example like this:

 1<project...>
 2 
 3  <build>
 4    <plugins>
 5      <plugin>
 6        <groupId>org.codehaus.mojo</groupId>
 7        <artifactId>exec-maven-plugin</artifactId>
 8        <version>3.0.0</version>
 9        <executions>
10          <execution>
11            <id>default-cli</id>
12            <configuration>
13              <mainClass>com.soebes.test.First</mainClass>
14            </configuration>
15          </execution>
16          <execution>
17            <id>second-cli</id>
18            <configuration>
19              <mainClass>com.soebes.test.Second</mainClass>
20            </configuration>
21          </execution>
22        </executions>
23      </plugin>
24    </plugins> 
25  </build>
26</project>

Now you can call Maven like this:

1$ mvn exec:java@second-cli

I would like to emphasize the @second-cli after the goal java which lets you select which of the given entries (<id>..</id>) will be used while invoking the goal. So now you can make a default configuration via <id>default-cli</id> and several other configuration which can be selected simply by giving the id during the command line invocation.

This opens a new level of command invocation configuration.

You might know the build-helper-maven-plugin which can be used in combination with the versions-maven-plugin to increment your versions without the maven-release-plugin via command line like this:

1 mvn build-helper:parse-version versions:set \
2     -DnewVersion=\${parsedVersion.nextMajorVersion}.0.0 \
3     versions:commit

In this invocation we are calling two different plugins with three goals. The first one is the build-helper-maven-plugin with the goal parse-version and the second versions-maven-plugin using the goal set and finally the versions-maven-plugin with the goal commit.

The parse-version goal reads the information of the pom.xml related to the version tag into plugin properties and produces some supplemental helpful new properties which can be used later for usage on the command line part: -DnewVersion=\${parsedVersion.nextMajorVersion}.0.0. This will use the property parsedVersion.nextMajorVersion and use it as input into the set goal to define a new major version. This means in the end it will increment the major version by one. The final commit goal will make the change of the pom.xml permanent. This could also being achieved by using the previously mentioned -DgenerateBackupPoms=false property.

As you already seen we have to use an escape before the $ to prevent any kind of shell to expand the information before even calling the plugin goals. Now a more important point is: Would you remember all the information needed to call that? I don't. There are further things possible like this (increment minor version by one):

1mvn build-helper:parse-version versions:set \
2     -DnewVersion=\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.0 \
3     versions:commit

That becomes more and more tedious and error-prone. We can improve that by using a pom.xml configuration (excerpt).

 1<plugin>
 2  <groupId>org.codehaus.mojo</groupId>
 3  <artifactId>versions-maven-plugin</artifactId>
 4  <executions>
 5    <execution>
 6      <id>major</id>
 7      <goals>
 8        <goal>set</goal>
 9      </goals>
10      <configuration>
11        <generateBackupPoms>false</generateBackupPoms>
12        <newVersion>${parsedVersion.nextMajorVersion}.0.0-SNAPSHOT</newVersion>
13      </configuration>
14    </execution>
15  </executions>
16</plugin>

So now you can use the following call to increment the major version of your project:

1$ mvn build-helper:parse-version versions:set@major

Much simpler isn't it? Apart from that it's much easier to remember and even simpler to configure in any kind of CI/CD solution and you don't have to fight with escaping in different environments. We can enhance further like this:

 1<plugin>
 2  <groupId>org.codehaus.mojo</groupId>
 3  <artifactId>versions-maven-plugin</artifactId>
 4  <executions>
 5    <execution>
 6      <id>major</id>
 7      <goals>
 8        <goal>set</goal>
 9      </goals>
10      <configuration>
11        <generateBackupPoms>false</generateBackupPoms>
12        <newVersion>${parsedVersion.nextMajorVersion}.0.0-SNAPSHOT</newVersion>
13      </configuration>
14    </execution>
15    <execution>
16      <id>minor</id>
17      <goals>
18        <goal>set</goal>
19      </goals>
20      <configuration>
21        <generateBackupPoms>false</generateBackupPoms>
22        <newVersion>${parsedVersion.majorVersion}.${parsedVersion.nextMinorVersion}.0-SNAPSHOT</newVersion>
23      </configuration>
24    </execution>
25    <execution>
26      <id>patch</id>
27      <goals>
28        <goal>set</goal>
29      </goals>
30      <configuration>
31        <generateBackupPoms>false</generateBackupPoms>
32        <newVersion>${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT</newVersion>
33      </configuration>
34    </execution>
35  </executions>
36</plugin>

So we can increment the minor version of our project via:

1$ mvn build-helper:parse-version versions:set@minor

The patch number like this:

1$ mvn build-helper:parse-version versions:set@patch

You might have spotted a small issue in the configuration because in each execution the <generateBackupPoms>false</generateBackupPoms> is duplicated? That can be solved very easy by refactoring that out like this:

 1<plugin>
 2  <groupId>org.codehaus.mojo</groupId>
 3  <artifactId>versions-maven-plugin</artifactId>
 4  <configuration>
 5    <generateBackupPoms>false</generateBackupPoms>
 6  </configuration>
 7  <executions>
 8    <execution>
 9      <id>major</id>
10      <goals>
11        <goal>set</goal>
12      </goals>
13      <configuration>
14        <newVersion>${parsedVersion.nextMajorVersion}.0.0-SNAPSHOT</newVersion>
15      </configuration>
16    </execution>
17    <execution>
18      <id>minor</id>
19      <goals>
20        <goal>set</goal>
21      </goals>
22      <configuration>
23        <newVersion>${parsedVersion.majorVersion}.${parsedVersion.nextMinorVersion}.0-SNAPSHOT</newVersion>
24      </configuration>
25    </execution>
26    <execution>
27      <id>patch</id>
28      <goals>
29        <goal>set</goal>
30      </goals>
31      <configuration>
32        <newVersion>${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT</newVersion>
33      </configuration>
34    </execution>
35  </executions>
36</plugin>

These are only some examples how the command line invocation can be tweaked by using the configuration options in Maven. I hope that helped a bit.