Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

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.

...

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
java
java
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 = "<goalName><goal-name>" ) is the minimal required annotation.
 * @since <since-text>
 * @deprecated <deprecated-text>
 */
@Mojo( name = "<goalName><goal-name>",
       aggregator = <false|true>, 
       configurator = "<roleHint><role-hint>",
       executionStrategy = "<once-per-session|always>",
       inheritByDefault = <true|false>,
       instantiationStrategy = InstanciationStrategy.<strategy>,
       defaultPhase = "<phaseName><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 = "<goalName><goal-name>",
          phase = LifecyclePhase.<phase>
          lifecycle = "<lifecycleId><lifecycle-id>" )
public class MyMojo
    extends AbstractMojo
{
    /**
     * @since <since-text>
     * @deprecated <deprecated-text>
     */
    @Parameter( alias = "myAlias",
                property = "aPropertya.property",
                defaultValue = "an expression with ${anExpressionvariables} eventually",
                readonly = <false|true>
                required = <false|true> )
    private String parameter;

    /**
     * @since <since-text>
     * @deprecated <deprecated-text>
     */
    @Component( role = "MyComponentExtension..."class,
                hint roleHint= "..." )
    private MyComponent component;

    public void execute()
    {
        ...
    }
}

Improvement Idea #1

rename roleHint to hint to match Plexus @Requirement

Code Block
java
java

    @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
java
java

    @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
java
java

    /**
     * @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 benefit