status: done in Maven Plugin Tools 3.0
Context
Maven plugins are described in META-INF/maven/plugin.xml descriptor, which is in general generated by maven-plugin-plugin. Information for the generator are written as javadoc annotations in java source: see maven-plugin-tools-java.
...
- JFrog's Maven Anno Mojo: see the wiki or annotations source,
the idea is having as much annotations as actual javadoc annotations, each with only 1 attribute - Maven MNG-2521, with its proposal from 2007 providing a source branch and its annotations,
the idea is having only 4 annotations each with multiple attributes: Goal + Execute and Parameter + Component
Proposal
Continue the work started on MNG-2521 before plugin-tools extraction from Maven Core.
Annotations:
- 4 annotations: Mojo, MojoExecute, MojoParameter and MojoComponent@Mojo and @Execute at class-level, @Parameter and @Component at field level
- java package: org.apache.maven.tools.plugin.annotations (consistent with maven-plugin-tools-api
- a new maven-plugin-tools-annotations component in plugin-tools
Extractor: addition into existing maven-plugin-tools-java
New features
- use annotations from parents classes coming from reactors and external dependencies.
Implementation
Initial work done in trunk http://svn.apache.org/repos/asf/maven/plugin-tools
...
The maven-plugin-plugin version has been bump to 3.0-SNAPSHOT.
State of the development as of 22/5/2012
Following usage for a plugin developer is working, with annotations near previous javadoc tags:
Code Block | ||||
---|---|---|---|---|
| ||||
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.InstanciationStrategy;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
/**
* Mojo Description. @Mojo( name = "<goal-name>" ) is the minimal required annotation.
* @since <since-text>
* @deprecated <deprecated-text>
*/
@Mojo( name = "<goal-name>",
aggregator = <false|true>,
configurator = "<role-hint>",
executionStrategy = "<once-per-session|always>",
inheritByDefault = <true|false>,
instantiationStrategy = InstanciationStrategy.<strategy>,
defaultPhase = "<phase-name>",
requiresDependencyResolution = ResolutionScope.<scope>,
requiresDependencyCollection = ResolutionScope.<scope>, // (since Maven 3.0)
requiresDirectInvocation = <false|true>,
requiresOnline = <false|true>,
requiresProject = <true|false>,
requiresReports = <false|true>, // (unsupported since Maven 3.0)
threadSafe = <false|true> ) // (since Maven 3.0)
@Execute( goal = "<goal-name>",
phase = LifecyclePhase.<phase>
lifecycle = "<lifecycle-id>" )
public class MyMojo
extends AbstractMojo
{
/**
* @since <since-text>
* @deprecated <deprecated-text>
*/
@Parameter( alias = "myAlias",
property = "a.property",
defaultValue = "an expression with ${variables} eventually",
readonly = <false|true>
required = <false|true> )
private String parameter;
/**
* @since <since-text>
* @deprecated <deprecated-text>
*/
@Component( role = MyComponentExtension.class,
hint = "..." )
private MyComponent component;
public void execute()
{
...
}
}
|
Improvement Idea #1
rename roleHint to hint to match Plexus @Requirement
Code Block | ||||
---|---|---|---|---|
| ||||
@Component( role = MyComponentExtension.class,
hint = "..." )
private MyComponent component;
|
DONE
Improvement Idea #2
Remove readonly attribute from @Parameter (was used for Maven components like ${project} to mark that it should not be configured by plugin user), and replace by a new attribute of @Component which is mutually exclusive with role+hint
Code Block | ||||
---|---|---|---|---|
| ||||
@Component( "project" )
private MavenProject project;
@Component( role = MyComponentExtension.class,
roleHint = "..." )
private MyComponent component;
|
evaluation: ${project.compileClasspathElements} is an expression that would be readonly but doesn't really resolve to a component, so the term isn't appropriate. Need a better term.
Improvement Idea #3
Introduce JSR-330, by requiring plugin developer to mark injected fields with standard @Inject and make @Parameter and @Component standard Qualifier.
Costs more writing for plugin developer (these @Inject) without much win other than mark the intent in a standard way (and shouldn't change much for maven-plugin-tools)
Code Block | ||||
---|---|---|---|---|
| ||||
/**
* @since <since-text>
* @deprecated <deprecated-text>
*/
@Inject
@Parameter( alias = "myAlias",
property = "aProperty",
defaultValue = "${anExpression}",
readonly = <false|true>
required = <false|true> )
private String parameter;
/**
* @since <since-text>
* @deprecated <deprecated-text>
*/
@Inject
@Component( role = MyComponentExtension.class,
roleHint = "..." )
private MyComponent component;
|
evaluation: since plugin.xml is still generated and content is injected by Maven core using this plugin.xml and not annotations taken from bytecode, this is not really useful and causes more confusion/harm than benefitExtractor: addition to maven-plugin-tools-java