Context
...
Maven plugins are described in
...
...
,
...
which
...
is
...
in
...
general
...
generated
...
by
...
...
.
...
Information
...
for
...
the
...
generator
...
are
...
written
...
as
...
javadoc
...
annotations
...
in
...
java
...
source:
...
...
.
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:
- 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 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
...
...
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 | ||||
---|---|---|---|---|
| ||||
{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 | ||||
---|---|---|---|---|
| ||||
@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 | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
{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