I currently am using the Exec Maven Plugin and it works fine with:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>myExec</id>
<goals>
<goal>exec</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<executable>myExec</executable>
<arguments>
<argument>--foo=${basedir}/src/test/resources/test.xml</argument>
<argument>--output-directory=target/generated-sources/output</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
I am also using the build helper plugin as follows:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/output</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
This is incredibly verbose however and I want multiple maven modules to be able to use this program and not have to retype all the exec plugin specific XML along with the builder XML.
Question: How do I possibly combine these 2 into another plugin?
I have used the maven archetype generator to generate a sample maven plugin and have a Mojo class:
@Mojo(name = "touch", defaultPhase = LifecyclePhase.PROCESS_SOURCES)
public class MyMojo
extends AbstractMojo
{
public void execute()
throws MojoExecutionException
{
ExecMojo exec = new ExecMojo();
}
}
And have figured out how to create a new ExecMojo.
Question How do I add the arguments here as I would in the XML above? And how can I integrate these arguments into my plugin?
Instead of creating your own Maven plugin, which may reduce portability and maintenability of your project, you may consider the following approach instead:
A simple parent pom would look like the following:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>sample-maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<path.to.myexec>path</path.to.myexec>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>myExec</id>
<goals>
<goal>exec</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<executable>${path.to.myexec}\myExec</executable>
<arguments>
<argument>--foo=${basedir}/src/test/resources/test.xml</argument>
<argument>--output-directory=${project.build.directory}/generated-sources/output</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/output</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>myexec-profile</id>
<build>
<plugins>
<!-- optionally move here the configuration above -->
</plugins>
</build>
</profile>
</profiles>
</project>
Note the path.to.myexec
property I added, to be overriden in children projects if required, in order to point to the correct relative path.
Then, once installed in your machine (or deployed in your company Maven repository), it can be referenced as following in any concerned Maven projects:
<parent>
<groupId>com.sample</groupId>
<artifactId>sample-maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
No need to re-declare the plugin configurations above and its verbose approach. They will be automatically part of the defaul build as part of the inherited build configuration from this parent.
The profiled approach can also be a solution if:
In such a case, you can then activate it via, as an example:
mvn clean package -Pmyexec-profile
Given that you already set the parent accordingly and you moved into the profile the configuration above.
Advantages of this approach:
mvn help: effective-pom
and see the merged full effective pom (as aggregate of parent and current pom) and check what it's actually runningHow to skip parent plugin executions in certain modules
A simple (and often used) approach to execute this plugins only in certain modules while having the parent in common with other modules is the following:
skip.script.generation
, with default value to true
, defined in the parent pom.skip
configuration entry of the plugins above. false
. This will be the only configuration required for their pom.xml
files, hence reduced to one line (keeping verbosity really low).The exec-maven-plugin
provides such a skip
option, unfortunately the build-helper-maven-plugin
doesn't. But that's not blocking us. We can still skip the two executions playing with their phase
element, setting it to a non existing phase, like none
and as such skipping them. This is suitable because the two executions are actually already attached to the same phase, generate-sources
.
For this approach, let's rename our new property to script.generation.phase
.
As an example:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>sample-maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<path.to.myexec>path</path.to.myexec>
<script.generation.phase>none</script.generation.phase>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>myExec</id>
<goals>
<goal>exec</goal>
</goals>
<phase>${script.generation.phase}</phase>
<configuration>
<executable>${path.to.myexec}\myExec</executable>
<arguments>
<argument>--foo=${basedir}/src/test/resources/test.xml</argument>
<argument>--output-directory=${project.build.directory}/generated-sources/output</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<phase>${script.generation.phase}</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/output</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>myexec-profile</id>
<build>
<plugins>
<!-- optionally move here the configuration above -->
</plugins>
</build>
</profile>
</profiles>
</project>
Note the <phase>${script.generation.phase}</phase>
changes for both plugins. With its default value to none
, this property is effectively disabling their executions by default.
In another module you would then have the following:
<parent>
<groupId>com.sample</groupId>
<artifactId>sample-maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<script.generation.phase>generate-sources</script.generation.phase>
</properties>
And nothing else. That is. Maven during the build will re-define the property for a certain module and automatically replace it in the configuration inherited from its parent and as such enabling again the two executions above.