Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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

...

.

Using java 5 annotations instead of javadoc ones have multiple benefits:

  • compile-time checks for plugin metadata, with enums for some annotations
  • inheritance support
  • annotations are supported in most IDEs, providing code-completion and syntactic checks

see plexus-component-annotations for an example of such a work done on Plexus.

Existing implementations

Multiple implementations of such annotations exist:

Proposal

Continue the work started on MNG-2521 before plugin-tools extraction from Maven Core.

Annotations:

  • 4 annotations: @Mojo and @Execute at class-level, @Parameter and @Component at field level
  • java package: org.apache.maven.tools.plugin.annotations

...

  • (consistent

...

  • with

...

...

  • a new maven-plugin-tools-annotations

...

  • component

...

  • in

...

...

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/trunk/

...

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


{code: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 = "<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()
    {
        ...
    }
}
{code}


h2. Improvement Idea #1

rename roleHint to hint to match Plexus @Requirement


{code:java}

Improvement Idea #1

rename roleHint to hint to match Plexus @Requirement

Code Block
java
java
    @Component( role = MyComponentExtension.class,
                hint = "..." )
    private MyComponent component;
{code}

*DONE*

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


h2. 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:java}
    @Component( "project" )
    private MavenProject project;

    @Component( role = MyComponentExtension.class,
                roleHint = "..." )
    private MyComponent component;
{code}


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


{code: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;
{code}

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