You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by Benjamin Bentmann <be...@udo.edu> on 2008/01/26 17:00:59 UTC

Plugin Parameters: expression vs. default-value

Hello,

The generated site documentation for many mojo parameters lacks the nice
info "Default value is <value>" in the parameter summary although the
parameter effectively has a default value. Take for instance the site for
the maven-resources-plugin and its "outputDirectory" parameter [0].

This effect originates from the subtle difference between

   /**
    * @parameter expression="${project.build.outputDirectory}"
    */
   private File outputDirectory;

and

   /**
    * @parameter default-value="${project.build.outputDirectory}"
    */
   private File outputDirectory;

when the PluginXDocGenerator creates the mojo report.

>From the user's point of view, there is no difference. In both cases, the
mojo can be used without explicitly specifying a value for the parameter
because a default value will be used. As a matter of consistency, the site
documentation should show this default value, regardless whether it comes
from "expression" or "default-value".

The question is, how can this be realized. I was just about to patch the
PluginXDocGenerator to do some kind of fallback like

    if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) )
    {
        // report default value
    }
    else if ( StringUtils.isNotEmpty( parameter.getExpression() ) )
    {
        // report expression as default value
    }

but hesitated when I imagined use-cases like

   /**
    * @parameter expression="${someSystemProperty}"
    */
   private File outputDirectory;

Here the expression is not backed by the POM and hence usually resolves to
null. It would be rather useless to report "${someSystemProperty}" as the
default value.

Currently I believe, plugin developers need to address this individually by
using "default-value" instead of "expression" when appropriate because there
does not seem to be an easy/reliable heuristic how the PluginXDocGenerator
can detect those cases.

A related question is whether it is sensible to do something like

   /**
    * @parameter expression="${project.build.outputDirectory}"
    * @required
    */
   private File outputDirectory;

i.e. use a POM-backed expression and also mark the parameter as required.
Again, from the user's point of view, this parameter is not required. It can
be safely ommited in the plugin configuration because the POM expression
will fill it in.

I know, that's all peanuts but Maven's documentation is often critized and I
feel this point is not on the good site. What do you think?

Regards,


Benjamin Bentmann


[0]
http://maven.apache.org/plugins/maven-resources-plugin/resources-mojo.html


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org


Re: Plugin Parameters: expression vs. default-value

Posted by Benjamin Bentmann <be...@udo.edu>.
> default-value is usually what plugin developers want, not expression.
> [...]
>
> In other words, expression results should not be allowed to
> reflectively query the build state, as in ${project.build.directory},

Thanks for clarifying this. Until you get a proper documentation up and
running, I suggest somebody reviews the Maven core plugins regarding this
topic. If you search for "${project." in the maven/plugins/trunk, you will
find dozens of mojo parameters that use expression rather than
default-value. I assume that many Non-Maven-Team developers (like me) look
at these plugins for an inspiration how things should be handled and
currently Maven's core plugins provide bad examples, that's pitty.

> That is, you don't want to allow users to customize this directory
> specifically for your plugin (which can be useful for trying to get
> plugins to standardize their locations and make them adjustable to
> changes in the entire build-output location of ./target), you should
> always add @readonly.

Personally, I think this practice should be avoided. Adding @readonly and
therefore hiding the parameter for configuration by the user is a rigid
enforcement. Conventions about directory locations or similar are nice but I
already have heard of people criticising Maven for its strictness, i.e. not
giving users a chance to break with the convention when they (for whatever
reason) need this.

When a plugin developer declares a mojo parameter like

  /*
   * @parameter default-value="${project.build.directory}/mytool"
   */
   private File outputDirectory;

The user can get standardized locations by simply tweaking the
POM.build.directory but he is also free to have some plugin derive from
this.

> At least, as Maven is currently implemented. This is because Maven
> will always choose *something* for the build directory, and also
> because ${missing.value}, when specified directly in the plugin
> config for outputDir, will resolve to the literal '${missing.value}'
> if you haven't specified a value for that expression in the system
> properties or pom properties.

Please note that Maven's evaluation of ${missing.value} does not match your
description. Unknown expressions resolve to null. I had to fight this when I
wanted to pass an expression from the plugin config throught to the plugin
itself, i.e. have the plugin evaluate the expression instead of Maven. In
the end, I had users to escape the expression by doubling the $. I just
verified this with Maven 2.0.8. If not already done, this subtle difference
might be worth an unit/integration test.

Regards,


Benjamin Bentmann


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org


Re: Plugin Parameters: expression vs. default-value

Posted by John Casey <jd...@commonjava.org>.
default-value is usually what plugin developers want, not expression.  
The reason we support both is to allow a default value extracted from  
the build state, but offer a name for the parameter that's different  
from the member variable name. It's an artifact of running for awhile  
without default-value in the plugin annotations that expression is  
resolved and used as a default value if the default value is missing.

In other words, expression results should not be allowed to  
reflectively query the build state, as in ${project.build.directory},  
but should be restricted to something like:

/**
  * @parameter expression="${myParamName}"
  */
private String param;

Another important best practice that should be documented and  
encourage is when to use @readonly. This is related to your last  
point, I think. When your default-value is something simple like $ 
{project.build.directory} and you intend to always use the  
configuration from:

<project>
   <build>
     <directory>target</directory>
   </build>
</project>

That is, you don't want to allow users to customize this directory  
specifically for your plugin (which can be useful for trying to get  
plugins to standardize their locations and make them adjustable to  
changes in the entire build-output location of ./target), you should  
always add @readonly. This prevents that parameter from being  
configured directly.

In general, it's probably redundant to specify:

/**
  * @parameter default-value="${project.build.directory}"
  * @required
  */
private String outputDir;

At least, as Maven is currently implemented. This is because Maven  
will always choose *something* for the build directory, and also  
because ${missing.value}, when specified directly in the plugin  
config for outputDir, will resolve to the literal '${missing.value}'  
if you haven't specified a value for that expression in the system  
properties or pom properties. IIRC, the only way @required will ever  
fail the build is if the resolved value is null (or maybe, the empty  
string)...so, until we introduce a change to prohibit $ 
{missing.value} => '${missing.value}' when dealing with plugin  
parameters, @required is of limited use when there is also a default- 
value (again, since that default value will always resolve to  
something, be that the literal expression or an actual value from the  
build state).

Hope that helps a little. I guess the doco needs some love in this  
respect.

Thanks,

-john

On Jan 26, 2008, at 11:00 AM, Benjamin Bentmann wrote:

> Hello,
>
> The generated site documentation for many mojo parameters lacks the  
> nice
> info "Default value is <value>" in the parameter summary although the
> parameter effectively has a default value. Take for instance the  
> site for
> the maven-resources-plugin and its "outputDirectory" parameter [0].
>
> This effect originates from the subtle difference between
>
>   /**
>    * @parameter expression="${project.build.outputDirectory}"
>    */
>   private File outputDirectory;
>
> and
>
>   /**
>    * @parameter default-value="${project.build.outputDirectory}"
>    */
>   private File outputDirectory;
>
> when the PluginXDocGenerator creates the mojo report.
>
> From the user's point of view, there is no difference. In both  
> cases, the
> mojo can be used without explicitly specifying a value for the  
> parameter
> because a default value will be used. As a matter of consistency,  
> the site
> documentation should show this default value, regardless whether it  
> comes
> from "expression" or "default-value".
>
> The question is, how can this be realized. I was just about to  
> patch the
> PluginXDocGenerator to do some kind of fallback like
>
>    if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) )
>    {
>        // report default value
>    }
>    else if ( StringUtils.isNotEmpty( parameter.getExpression() ) )
>    {
>        // report expression as default value
>    }
>
> but hesitated when I imagined use-cases like
>
>   /**
>    * @parameter expression="${someSystemProperty}"
>    */
>   private File outputDirectory;
>
> Here the expression is not backed by the POM and hence usually  
> resolves to
> null. It would be rather useless to report "${someSystemProperty}"  
> as the
> default value.
>
> Currently I believe, plugin developers need to address this  
> individually by
> using "default-value" instead of "expression" when appropriate  
> because there
> does not seem to be an easy/reliable heuristic how the  
> PluginXDocGenerator
> can detect those cases.
>
> A related question is whether it is sensible to do something like
>
>   /**
>    * @parameter expression="${project.build.outputDirectory}"
>    * @required
>    */
>   private File outputDirectory;
>
> i.e. use a POM-backed expression and also mark the parameter as  
> required.
> Again, from the user's point of view, this parameter is not  
> required. It can
> be safely ommited in the plugin configuration because the POM  
> expression
> will fill it in.
>
> I know, that's all peanuts but Maven's documentation is often  
> critized and I
> feel this point is not on the good site. What do you think?
>
> Regards,
>
>
> Benjamin Bentmann
>
>
> [0]
> http://maven.apache.org/plugins/maven-resources-plugin/resources- 
> mojo.html
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
> For additional commands, e-mail: dev-help@maven.apache.org
>

---
John Casey
Committer and PMC Member, Apache Maven
mail: jdcasey at commonjava dot org
blog: http://www.ejlife.net/blogs/john
rss: http://feeds.feedburner.com/ejlife/john



RE: Plugin Parameters: expression vs. default-value

Posted by "Brian E. Fox" <br...@reply.infinity.nu>.
>   /**
>   * @parameter expression="${project.build.outputDirectory}"
>    */
>   private File outputDirectory;

>and

>   /**
>    * @parameter default-value="${project.build.outputDirectory}"
>    */
>   private File outputDirectory;

Interesting problem. I usually prefer to use the expression for anything
property related and default-value to specify a value in the case the
property didn't resolve.

>Here the expression is not backed by the POM and hence usually resolves
to
>null. It would be rather useless to report "${someSystemProperty}" as
the
>default value.

If we see a property syntax in the default-value, why not display it as
though it was an expression? Expressions currently show the property
name on the site.

>Currently I believe, plugin developers need to address this
individually by
>using "default-value" instead of "expression" when appropriate because
there
>does not seem to be an easy/reliable heuristic how the
PluginXDocGenerator
>can detect those cases.

I agree it should be consistent and this comes back to documenting the
best practices so everyone knows.


>   /**
>    * @parameter expression="${project.build.outputDirectory}"
>    * @required
>    */
>   private File outputDirectory;

>i.e. use a POM-backed expression and also mark the parameter as
required.
>Again, from the user's point of view, this parameter is not required.
It can
>be safely ommited in the plugin configuration because the POM
expression
>will fill it in.

The plugin annotation parser should be smart enough to see this as well
and ignore the @required if an expression or default-value is given.

>I know, that's all peanuts but Maven's documentation is often critized
and I
>feel this point is not on the good site. What do you think?

I agree these are important, and we need to document and then fix them.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org