Groovy 1.7.3: AnnoMojo + GroovyMojo!
I waited a lot. Oh boy, I did.
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”
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:
publicmodifiers- 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.
Backup techniques. Saving my life. Hudson and Artifactory Maven repository



[...] Groovy 1.7.3: AnnoMojo + GroovyMojo! [...]
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.
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″?
I’ve found root cause: current/latest AnnoMojo version is incompatible with maven 3.
Ah! That’s an issue to be opened to them. Can you, please, do so?
I also use a forum, they’re very responsive.
Yes, it was from plugin-plugin. I’ve used 2.5.1 and 2.6, w/o difference
http://issues.jfrog.org/jira/browse/ANMJ-17
Voted!
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”)
^
Hi Neil, AnnoMojo dependency seems to be missing. You can take a look on my project, where all plugins are Groovy Mojos: https://github.com/evgeny-goldin/maven-plugins.
Thanks. Will study that.
There’s a simpler project that I just started: https://github.com/evgeny-goldin/gmaven-samples
It demonstrates all basic GMaven plugin usages. You can look in “build-groovy-mojo” module, it contains everything required and creates a simple Maven plugin. “run-groovy-mojo” module uses this plugin.
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
Thanks, Tim. Glad I could help. There are some more GMaven examples at https://github.com/evgeny-goldin/gmaven-samples. Have you tried GMavenPlus (https://github.com/keeganwitt/GMavenPlus) ? It’s supposed to replace GMaven, I plan to switch to it soon.