Now that we explored the core concepts of Maven, we know that all the work is done by Maven plugins. We can say that there are no exceptions to this rule. Till now, we saw some core and packaging plugins such as the Maven Compiler Plugin, the Maven Install Plugin, the and the Maven JAR Plugin. We also learned how to explore their goals and properties using the Maven Help Plugin. What we have to know is how to customize the behavior of the plugins that are already bound by default to the build lifecycle and how to fill the lifecycle with the other required plugin goals.
If we need to configure a plugin, we can specify some common configuration parameters that will be used for all the invocations of the plugin within our project. This means that such parameters will be used both when we invoke a plugin goal directly from the command line (in the project directory) and when the plugin is invoked during a phase of the build lifecycle. We can achieve this putting a <configuration>
element into the <plugin>
element related to our plugin in the project POM. An abstract example is the following:
<project> [...] <build> <plugins> <plugin> <groupId>...</groupId> <artifactId>...</artifactId> <version>...</version> <configuration> <param1>value1</param1> <param2>value2</param2> [...] </configuration> </plugin> </plugins> </build> [...] </project>
We have to remark on this:
–Ddetail
option. Using the Maven Help Plugin, we can also see the default values for all the plugin parameters.If we look at the parent POM of our sample project introduced in the previous chapter, we will see that we set the source and target parameters to 1.7 in order to compile with JDK 1.7:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin>
If we use the version 2.5.1 of the Maven Compiler Plugin the default values for both these parameters are 1.5, so we need to change them.
A plugin can be bound to more than one phase of the lifecycle. We can execute multiple goals or the same goal more than once in the same phase or in different phases. To obtain this, we can use multiple <execution>
elements, each containing the <configuration>
element to be considered for the execution. In the same manner, when a plugin is not bound by default to the build lifecycle, we have to specify an <execution>
element with its configuration. The plugin-level and execution-level configuration can coexist, in which case, the execution-level configuration settings will override the plugin-level settings.
Let's consider an example. Suppose we have to generate the JAXB beans from a given XSD schema and we want to put them into the transportation-common-jar
module of our sample project. We can use jaxb2-maven-plugin
and bind it to the generate-sources
phase of the lifecycle, as follows:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>1.6</version> <executions> <execution> <id>myExecution</id> <goals> <goal>xjc</goal> </goals> <configuration> <schemaDirectory> src/main/resources/schema/ </schemaDirectory> <bindingDirectory>src/main/resources/xjb</bindingDirectory> <arguments>-extension</arguments> </configuration> </execution> </executions> </plugin>
If we put one or more XSD files in the schema directory and we build the project, we'll see the following output:
$ mvn install [...] [INFO] --- jaxb2-maven-plugin:1.6:xjc (myExecution) @ transportation-common-jar --- [INFO] Generating source... [...] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ transportation-common-jar --- [...] [INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ transportation-common-jar --- [...]
We'll notice that the JAXB beans have been generated in the /target/generated-sources/jaxb
directory, which is the default value for the outputDirectory
configuration parameter of the JAXB-2 Maven Plugin. Also, schemaDirectory
and bindingDirectory
have default values, but in this case, they have been overridden in the execution-level configuration.
The compiler plugin is able to compile the generated sources in addition to those in /src/main/java
.
We have to remark on this:
<execution>
element and goal specification are needed. If they are missing, no goals will be executed. This is because no goals of jaxb2-maven-plugin
are bound by default to the default lifecycle.<phase>generate-sources</phase>
child element of the <execution>
element, but in this case, it is not needed because the binding of the xjc
goal to the generate-sources
phase is a default setting for jaxb2-maven-plugin
and is defined within the plugin itself. We can discover the default phase for a plugin goal using the Maven Help Plugin, as suggested earlier.The execution ID, which is the <id>
child element of the <execution>
element, is not mandatory. If it misses a value, default
will be used. When we need to configure plugins that are already bound to the Maven lifecycle (for example, compiler-maven-plugin
or ear-maven-plugin
), we should know that each plugin goal invoked by the build process will have the default-<goalName>
execution ID assigned to it. For example, maven-compiler-plugin
is executed twice during the default lifecycle: during the compile
phase, the compile
goal is executed with the default-compile
execution ID; during the test-compile
phase, the testCompile
goal is executed with the default-testCompile
execution ID. This way, we'll be able to configure the two executions independently. We can verify this behavior looking at the Maven output of the previous examples. In the case of direct invocation of a plugin goal, the execution ID will always be default-cli
. Let's see an example about the configuration of a plugin that is invoked directly: suppose we don't want to bind the JAXB-2 Maven Plugin to the generate-sources
phase, and we want to invoke this plugin directly (and only once) to generate the JAXB beans under the /src/main/java
source folder. All we have to do is modify the plugin configuration as follows:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>1.6</version> <executions> <execution> <id>default-cli</id> <configuration> <schemaDirectory>src/main/resources/schema/</schemaDirectory> <bindingDirectory>src/main/resources/xjb</bindingDirectory> <outputDirectory>src/main/java</outputDirectory> <arguments>-extension</arguments> </configuration> </execution> </executions> </plugin>
This way, the xjc
plugin goal will not be bound to the generate-sources
phase because no goals are specified. If we want to generate the JAXB beans, we have to use the following command, and the configuration of the default-cli execution ID will be used:
$ mvn jaxb2:xjc
We need to notice that we cannot have multiple executions with different configurations for direct invocation because only the default-cli
execution ID is available.
We can find more examples about this on the Maven site at the following URL:
http://maven.apache.org/guides/mini/guide-default-execution-ids.html