More on Plugins

This lesson continues the discussion on plugins and how to exercise them.

In the previous lesson, we added the plugin configuration. If the effective POM were computed, the section pertaining to the clean plugin would have been as follows:

<plugin>
    <artifactId>maven-clean-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <execution>
            <id>default-clean</id>
            <phase>clean</phase>
            <goals>
                <goal>clean</goal>
            </goals>
            <configuration>
                <verbose>true</verbose>
                <outputDirectory>/Project11/test</outputDirectory>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <verbose>true</verbose>
        <outputDirectory>/Project11/test</outputDirectory>
    </configuration>
</plugin>

We didn’t discuss the element <execution> previously and we didn’t need to because the clean goal was already bound to the _clean phase _of the clean lifecycle. In this lesson, we’ll use a different plugin to execute a shell script and learn how to bind it to different phases of a lifecycle. We’ll use the exec-maven-plugin and invoke its exec goal. The goal will execute a bash script named myScript.sh that will print a message on the console. Specifically, we’ll be adding the following snippet to the POM of Project12 in the exercise that follows.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.2</version>
    <executions>
        <execution>
            <id>my-special-exec</id>
            <phase>install</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>/Project12/myScript.sh</executable>
            </configuration>
        </execution>
    </executions>
</plugin>

The <plugin> element identifies the plugin we want to execute with the coordinates: groupId, artifactId, and version. Next, the <executions> element contains information about when we want to execute a particular goal of the plugin. The other elements are discussed below:

  1. id: is the identifier for the execution. IDs have to be unique among all executions of a single plugin within a POM. They don’t have to be unique across an inheritance hierarchy of POMs. We can invoke a plugin using the ID on the command line directly.

  2. phase: is the phase of a lifecycle the goal is bound to, i.e. the stage within the lifecycle when the goal would get executed. We can also skip the phase, if the goal already has a default phase bound to it within which it executes, e.g., as we saw in the case of the clean plugin. But if the goal is not bound to any lifecycle phase then it simply won’t be executed.

  3. goal: The name of the goal we wish to execute. For our example, we want to execute the goal exec. The plugin also offers another goal by the name of java.

  4. configuration: Under the configuration element we’ll add all the plugin specific parameters and their values. The astute reader may question why the <configuration> element for the clean plugin appears twice in the first exhibit. The reason is, prior to Maven 3.3.1 if we wanted to invoke a plugin goal directly from the command line, the configuration in the POM wouldn’t apply since it resided within the <executions> element and took effect only when the lifecycle phase it was bound to, was invoked. To have the configuration apply when the goal is invoked on the command line, the <configuration> element had to be taken outside of <executions>. With the latest Maven version, this isn’t the case anymore as we can also invoke a goal with a particular execution context using the execution ID as follows:

mvn <plugin-prefix>:<plugin-goal>@<execution-id>

## e.g. for our example, the invocation will be:

mvn exec:exec@my-special-exec

Note, that if we try to invoke the plugin goal by itself on the command line mvn exec:exec, it’ll fail because there’s no associated configuration. We can duplicate the <configuration> element from the <execution> section and insert it after the <executions> element in the POM file. This would allow the goal to execute by itself without having to be part of a lifecycle phase, because the configuration outside the <executions> applies globally to all invocations of the plugin.

  1. dependencies: Though not covered in this example, if a plugin is dependent on other artifacts, we can add them as a dependency and specify the desired version for the plugin to use.

  2. inherited: Plugin configuration is propagated to child POMs by default but in case we want to break the inheritance, we can use the <inherited> tag and set it to false. We’ll see a practical example of its use in later lessons.

Get hands-on with 1200+ tech skills courses.