RSS
 

Groovy 1.7.3: AnnoMojo + GroovyMojo!

27 Jun



I waited a lot. Oh boy, I did.

 

.. Rewind back half a year ..

 

Writing Maven plugins, or MOJOs, is a real need when you work with Maven. It just feels unnatural not to.

Default Maven behavior and set of plugins is only good for common situations and the moment you’re doing something unusual, like running Spring Batch jobs or generating Hudson jobs in your POM, Maven doesn’t really deliver. In the last year, I had to develop about 10 Maven plugins, now waiting for a final Thomson Reuters approval to be open-sourced (stay tuned!)

Initially, I used Java but later switched to Groovy, for an obvious reasons. With Gmaven plugin it is very easy to develop Groovy Mojos. Good!

The only problem I had after switching to Groovy is lack of Anno Mojo support providing Java 5 annotations to MOJO developer.

Java:

@MojoGoal("doIt")
@MojoPhase("package")
public class MyMojo extends AbstractMojo
{
    @MojoComponent
    private ArtifactFactory artifactFactory;

    @MojoParameter(expression = "${project}", required = true)
    private MavenProject project;

    @MojoParameter (required = false)
    private String runIf;
    ...
}

Groovy:

@MojoGoal("doIt")
@MojoPhase("package")
class MyMojo extends GroovyMojo
{
    @MojoComponent
    def ArtifactFactory artifactFactory;

    @MojoParameter(expression = "${project}", required = true)
    def MavenProject project;

    @MojoParameter (required = false)
    def String runIf;
    ...
}

Groovy version didn’t work :(
Meet “GROOVY-4118″ – “JavaStubGenerator doesn’t generate annotations available in Groovy code”

 

.. Fast forward to Groovy 1.7.3 release ..

 

Shortly before Groovy 1.7.3 release the issue above was addressed and fixed by Paul King and Jochen Theodorou. After some more attempts I made it work and it felt really-really good to get back annotations in Groovy Mojos!

@MojoGoal("doIt")
@MojoPhase("package")
class MyMojo extends GroovyMojo
{
    @MojoComponent
    public ArtifactFactory artifactFactory;

    @MojoParameter(expression = "${project}", required = true)
    public MavenProject project;

    @MojoParameter (required = false)
    public String runIf;
    ...
}

It is required to use:

  • public modifiers
  • Groovy fields

This will not work:

class MyMojo extends GroovyMojo
{
    @MojoParameter (required = false)
    def String runIf;

    @MojoParameter (required = false)
    String something;
}

 

"pom.xml":

<dependencies>
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <!-- To use Anno Mojo annotations in Groovy code -->
    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
    <dependency>
        <!-- http://www.jfrog.org/artifactory/plugins-releases/org/jfrog/maven/annomojo/maven-plugin-anno/ -->
        <groupid>org.jfrog.maven.annomojo</groupid>
        <artifactid>maven-plugin-anno</artifactid>
        <version>1.3.3</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupid>org.codehaus.groovy</groupid>
        <artifactid>groovy-all</artifactid>
        <version>1.7.3</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
        <!-- To generate Java stubs and compile Groovy classes -->
        <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
        <plugin>
            <groupid>org.codehaus.gmaven</groupid>
            <artifactid>gmaven-plugin</artifactid>
            <version>1.2</version>
            <executions>
                <execution>
                    <id>generate-stubs</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>generateStubs</goal>
                    </goals>
                </execution>
                <execution>
                    <id>compile-groovy</id>
                    <phase>process-sources</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <providerselection>1.7</providerselection>
                <verbose>true</verbose>
                <sources>
                    <fileset>
                        <directory>${projects.basedir}/src/main/scripts</directory>
                        <includes>
                            <include>**/*.groovy</include>
                        </includes>
                    </fileset>
                </sources>
            </configuration>
            <dependencies>
                <dependency>
                    <groupid>org.codehaus.gmaven.runtime</groupid>
                    <artifactid>gmaven-runtime-1.7</artifactid>
                    <version>1.2</version>
                    <exclusions>
                        <exclusion>
                            <groupid>org.codehaus.groovy</groupid>
                            <artifactid>groovy-all</artifactid>
                        </exclusion>
                    </exclusions>
                </dependency>
                <dependency>
                    <groupid>org.codehaus.groovy</groupid>
                    <artifactid>groovy-all</artifactid>
                    <version>1.7.3</version>
                </dependency>
            </dependencies>
        </plugin>

        <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
        <!-- To "activate" Anno Mojo during plugin metadata generation -->
        <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
        <plugin>
            <groupid>org.apache.maven.plugins</groupid>
            <artifactid>maven-plugin-plugin</artifactid>
            <version>2.5.1</version>
            <dependencies>
                <dependency>
                  <groupid>org.apache.maven.plugin-tools</groupid>
                  <artifactid>maven-plugin-tools-api</artifactid>
                  <version>2.5.1</version>
                </dependency>
                <dependency>
                    <!-- http://www.jfrog.org/artifactory/plugins-releases/org/jfrog/maven/annomojo/maven-plugin-tools-anno/ -->
                    <groupid>org.jfrog.maven.annomojo</groupid>
                    <artifactid>maven-plugin-tools-anno</artifactid>
                    <version>1.3.3</version>
                    <scope>runtime</scope>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

Also, I use the following base class for all Groovy Mojos with commonly-used @MojoParameters:

/**
 * Base GroovyMojo class
 */
abstract class ClfGroovyMojo extends GroovyMojo
{
    private static final Log LOG = new SystemStreamLog()
    public  static       Log getLog () { LOG }

    @MojoParameter ( expression = '${project}' )
    public MavenProject mavenProject
    public MavenProject mavenProject() { this.@mavenProject }

    @MojoParameter ( expression = '${session}' )
    public MavenSession mavenSession
    public MavenSession mavenSession() { this.@mavenSession }

    @MojoParameter ( expression = '${project.build.directory}' )
    public File buildDirectory
    public File buildDirectory() { this.@buildDirectory }

    @MojoParameter ( expression = '${project.build.outputDirectory}' )
    public File outputDirectory
    public File outputDirectory() { this.@outputDirectory }

    @MojoParameter ( expression = '${project.basedir}' )
    public File basedir
    public File basedir() { this.@basedir }

    @MojoParameter ( defaultValue = '${localRepository}' )
    public ArtifactRepository localRepository
    public ArtifactRepository localRepository() { this.@localRepository }

    @MojoComponent
    public PluginManager pluginManager
    public PluginManager pluginManager() { this.@pluginManager }
}

Let me know if something doesn’t work for you. I may provide a complete example of Groovy Mojo.

 
 

Tags: , , ,

Leave a Reply

 

 
  1. Moving this blog to “evgeny-goldin.com” « Goldin, the Junior

    June 27, 2010 at 2:10 AM

    [...] Groovy 1.7.3: AnnoMojo + GroovyMojo! [...]

     
  2. Sergey

    June 30, 2010 at 10:01 AM

    Evgeny, thanks for solution!

    Could you provide complete pom please?

    I’m trying to reuse provided one, but got an exception:

    Caused by: org.apache.maven.plugin.MojoExecutionException: The API of the mojo scanner is not compatible with this plugin version. Please check the plugin dependencies configured in the POM and ensure the versions match.

     
    • Evgeny Goldin

      June 30, 2010 at 10:09 AM

      Ok, I’ll work on it later this week. Meanwhile, can you, please, provide the stack trace of this exception? It’s most probably coming “maven-plugin-plugin”. Is it of version “2.5.1″?

       
  3. Sergey

    June 30, 2010 at 10:12 AM

    I’ve found root cause: current/latest AnnoMojo version is incompatible with maven 3.

     
  4. Sergey

    June 30, 2010 at 11:24 AM

    Yes, it was from plugin-plugin. I’ve used 2.5.1 and 2.6, w/o difference

     
  5. Sergey

    June 30, 2010 at 12:19 PM

     
  6. Neil

    April 22, 2011 at 2:04 PM

    I’m missing a dependency somewhere?! I copied and pasted the above as a test….

    /home/neil/workspace/testMojo/src/TestMojo.groovy: 1: unable to resolve class GroovyMojo
    @ line 1, column 1.
    @MojoGoal(“doIt”)
    ^

    /home/neil/workspace/testMojo/src/TestMojo.groovy: 1: unable to resolve class MojoGoal , unable to find class for annotation
    @ line 1, column 1.
    @MojoGoal(“doIt”)
    ^

    /home/neil/workspace/testMojo/src/TestMojo.groovy: 2: unable to resolve class MojoPhase , unable to find class for annotation
    @ line 2, column 1.
    @MojoPhase(“package”)
    ^

     
  7. Tim Drury

    December 2, 2011 at 6:25 PM

    Evgeny, thanks for the blog entry. It was crucial to get my gmaven plugin working: http://tdruryjavanotes.blogspot.com/2011/12/cobertura-for-integration-testing.html

    Take care,
    -tim