home.


Tagged: maven-plugins


Maven p12: Plugins p5: Creating your own lifecycle

We can also define custom lifecycles, that are run via a mojo plugin. These are run in parallel to the current lifecycle.

Create src/main/resources/META-INF/maven/lifecycle.xml:

    <lifecycles>
       <lifecycle>
       <id>customlifecycle</id>
         <phases>
             <phase>
          <id>compile</id>
          <executions>
              <execution>
              <goals>
                  <goal>test</goal>
                  <goal>test</goal>                            
              </goals>                        
              </execution>
          </executions>
             </phase>
         </phases>
       </lifecycle>
    </lifecycles>

It creates a new lifecycle, with a name, and specifies the phases. Each phase is named compile, clean etc, but the executions therein can have multiple custom goals. In this case we’re defining the ‘test’ goal we defined in a plugin previously to run twice on the compile phase.

To run this lifecycle, we need an empty plugin, that specifies this lifecycle, with its goals, must be run:

    package org.denevell.mavenplugins;

    import org.apache.maven.plugin.AbstractMojo;
    import org.apache.maven.plugin.MojoExecutionException;
    import org.apache.maven.plugin.MojoFailureException;

    /**
     * @goal lifecycleloader 
     * @execute lifecycle="customlifecycle" phase="compile"
     */
    public class LifecycleloaderMojo extends AbstractMojo {

       public void execute() 
          throws MojoExecutionException, MojoFailureException {
       }

    }

It’s saying in the @execute lifecycle=‘ourlifecycle’ phase=‘compile’ that we should run the ourlifecycle lifecycle, specificially the ‘compile’ phase. This then needs to be put in our components.xml file (which we looked at in the previous tutorial):

    <component-set>
       <components>
         <component>
          <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
          <role-hint>ourlifecyclepackage</role-hint>
          <implementation>
              org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping
          </implementation>
          <configuration>
              <phases>
                 <package>
                   org.denevell.mavenplugins:some_plugin:lifecycleloader              
                 </package>
              </phases>
          </configuration>
         </component>
       </components>
    </component-set>

So when we get to the compile phase of our package, that then loads the LifecycleLoaderMojo plugin, which in turn loads our ourlifecycle lifecycle in its compile phase, which runs two instances of our ‘test’ goal.

maven maven-plugins

Maven p11: Plugins p4: adding it to a lifecycle

Lifecycles package types are the values inbetween the packaging tags underneath the main project tag. They’re normally jar, or similar, and define what to do on each compile, clean, package, etc phase. We can define our own, and run one of our plugin classes on a particular phase.

In src/main/resources/META-INF/plexus/components.xml create

    <component-set>
       <components>
         <component>
          <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
          <role-hint>ourlifecyclepackage</role-hint>
          <implementation>
              org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping
          </implementation>
          <configuration>
              <phases>
                 <compile>
                   org.denevell.mavenplugins:some_plugin:test
                 </compile>
              </phases>
          </configuration>
         </component>
       </components>
    </component-set>

It defines a component that is a lifecycle mapping, has the name ourlifecycle, is implemented using the DefaultLifecycle, and its configuration tag says it is overriding the compile phase with the plugin (defined groupdId:artifactId:goal) that we defined before. We can put multiple goals using commas.

Now if you mvn clean install this plugin we can use it elsewhere. Let’s create a new project. It has nothing in it, except this pom.xml:

    <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/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>org.denevell.mavenplugins</groupId>
      <artifactId>another_test</artifactId>
      <packaging>ourlifecyclepackage</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>another_test</name>
      <build>
         <plugins>
            <plugin>
              <groupId>org.denevell.mavenplugins</groupId>
              <artifactId>weblog_plugin</artifactId>
              <extensions>true</extensions>
              <version>1.0-SNAPSHOT</version>
              <configuration>
          <message>HALLO</message>
              </configuration>
            </plugin>
         </plugins>
      </build>
    </project>

This is very similar to the last time we used our plugin in another pom. However, there’s now no executions tag, as the plugin is executed as part for the compile cycle, as defined in our components.xml. And the extensions tag set to true allow us to use the lifecycle name, ourlifecyclepackage, in the packaging tag.

Now if you mvn clean package, you’ll see the plugin is executed, displaying the configured HALLO text. Note, although we only defined a compile phase in our components.xml, we still get the defaults from the superpom, ‘package’ in this case. We only overrode the compile phase.

maven maven-plugins

Maven p8: Plugins p3

Now we’ve got a plugin, we’ll add it to a project.

I’ve simply created a new directory with this pom.xml. It says it’s creating a jar. But the jar’s empty. This is just to see the plugin in action.

There are a few new things, to be noted afterwards.

    <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/maven-v4_0_0.xsd">
         <modelVersion>4.0.0</modelVersion>
         <groupId>org.denevell.mavenplugins</groupId>
         <artifactId>another_test</artifactId>
         <packaging>jar</packaging>
         <version>1.0-SNAPSHOT</version>
         <name>another_test</name>
         <build>
          <plugins>
              <plugin>
                 <groupId>org.denevell.mavenplugins</groupId>
                 <artifactId>some_plugin</artifactId>
                 <version>1.0-SNAPSHOT</version>
                 <configuration>
                   <message>HALLO</message>
                 </configuration>
                 <executions>
                   <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>test</goal>
                    </goals>
                   </execution>
                 </executions>
              </plugin>
          </plugins>
         </build>
       </project>

The build tag has a plugin tag. Within we give it the group and artifact of the previously defined plugin, plus the version. The configuration is to pass the our.message parameter. We leave out the first part, for some reason. If we were setting this in the properties tag, under the project tag, we’d use our.message.

The execution tag says run the defined ‘test’ goal in the compile stage. And if we run mvn install, we’ll see our output, ‘HALLO’ in this case, on the screen.

maven maven-plugins

Maven p7: Plugins p2

You can also pass parameters to your java class.

    /**
     * @parameter expression="${our.message}" default-value="default message, innit"
     */
    private Object message;

    public void execute() 
    throws MojoExecutionException, MojoFailureException {
       getLog().info(message.toString());
    }

Note that the @parameter is injecting a value, of our.message, into the ‘message’ variable, giving it a default message if that doesn’t exist.

The last part of the parameter, message in this case, must match the java object name.

If you add -Dour.message=“something else” on the previous command we ran to execute the plugin, we’ll output ‘something else’ instead of the default.

You can also add it in your pom.xml when you include this plugin into another project. More on that next.

maven maven-plugins

Maven p6: Plugins p1

Doing any compilation that’s custom, that’s not provided for using other plugins, requires writing your own. First create a ‘archetype’ of a plugin; that is, create the template:

    mvn archetype:create \
       -DgroupId=org.denevell.mavenplugins \
       -DartifactId=some_plugin \
       -DarchetypeGroupdId=org.apache.maven.archetypes \
       -DarchetypeArtifactId=maven-archetype-mojo

This will create that template, using the maven-plugin-api as a dependency.

Now you need to create a class that actually performs something on behalf of the plugin. Those things are called mojos. In the source directory, create this class.

    package org.denevell.mavenplugins;

    import org.apache.maven.plugin.AbstractMojo;
    import org.apache.maven.plugin.MojoExecutionException;
    import org.apache.maven.plugin.MojoFailureException;

    /**
     * @goal test
     * @author yooou
     *
     */
    public class TestMojo extends AbstractMojo {

       @Override
       public void execute() 
         throws MojoExecutionException, MojoFailureException {
          getLog().info("hellooooo");
         }

    }

Note the @goal attribute. This is the name you will use to call this. The execute() method is called. And we’re using getLog() to log something to the screen.

Now if you run ‘mvn install’, you can use this plugin. Let’s use the command line at first:

    mvn org.denevell.mavenplugins:some_plugin:1.0-SNAPSHOT:test

It’s of the form groupdId:artifactId:version:goal

maven maven-plugins

Page 1 of 1