views:

135

answers:

3

In the Maven document Introduction to the Build Lifecycle, a goal of display:time is described that outputs the current time. The plugin is as follows:

...
<plugin>
  <groupId>com.mycompany.example</groupId>
  <artifactId>maven-touch-plugin</artifactId>
  <version>1.0</version>
  <executions>
    <execution>
      <phase>process-test-resources</phase>
      <goals>
        <goal>timestamp</goal>
      </goals>
    </execution>
  </executions>
</plugin>
...

I have several questions relating to this plugin:

  1. How can I change the name of the goal to, for example, foo:bar? (Why does neither display nor time appear anywhere in the XML fragment? How can you tell, from looking at the fragment, what goals it defines?)
  2. How can I manually run this goal? (For similar constructs, the equivalent of mvn display:time sometimes works, but this doesn't work consistently.)
  3. How can I see if this goal exists? (i.e. list available goals; this question suggests this is impossible.)
A: 

To your first one. The name of the goal is defined by the plugin (there is an annotation for that). If have the source code you change that. Taking a look at the XML you can't know what kind of goals a plugin defines only the ones which are given in the XML. The best location is to look at the documentation of the plugin. Second one: You have to check the docs. Usually pluginname:goal ...May be you have to specify the full path of the plugin (groupId). To the third: Usually should be able to use the help plugin take a look at the docs.

khmarbaise
+2  A: 

I think there's a chance that the documentation may have a typo. Plugin goals are specified by plugin-name:goal-name. That XML would bind the goal touch:timestamp to the process-test-resources phase. That fragment doesn't have anything to do with display:time.

  1. As far as I know, it is impossible to rename maven goals. (It seems like it would just make things more confusing.) The plugin source code is what defines goals, not the pom. The <executions> tag in the pom merely allows you to bind plugin goals to phases, or rebind goals if they already have a default phase.

  2. You should be able to run a goal with prefix:goalName. Most often, the prefix is simply whatever is between "maven-" and "-plugin" in the artifactId. e.g. touch:timestamp. This is complicated in a few situations since plugin authors can specify a "goalPrefix" different from the plugin name, but I haven't ever run into problems with this.

  3. The best way to find out what goals a plugin defines, and what phases they are bound to by default is to read the plugin documentation.

takteek
+3  A: 

How can I change the name of the goal to, for example, foo:bar? (Why does neither display nor time appear anywhere in the XML fragment? How can you tell, from looking at the fragment, what goals it defines?)

To be precise, in foo:bar, foo is the "plugin goal prefix" and bar is the "goal". And while the later is derived from naming conventions (or can be configured1), the former comes from an annotation of the BarMojo, the class that implements the plugin logic. Something like this:

/**
 * Do the wonderful bar.
 * @goal bar
 * @requiresProject false
 */
public class BarMojo extends AbstractMojo
{
    ...
}

Changing the goal requires modifying the annotation of the mojo of a plugin and rebuilding it.

Regarding the documentation you linked to, there is a clearly mismatch between the goal time and the XML fragment which binds a timestamp goal to the process-test-resources phase. This must be a typo.

How can I manually run this goal? (For similar constructs, the equivalent of mvn display:time sometimes works, but this doesn't work consistently.)

You can call it like this:

mvn com.mycompany.example:maven-touch-plugin:1.0:timestamp

You could make this command shorter by adding com.mycompany.example to the Plugin Groups in your settings.xml (org.apache.maven.plugins and org.codehaus.mojo are declared by default in case you wonder how it works for those plugins)

<settings>
  ...
  <pluginGroups>
    <pluginGroup>com.mycompany.example</pluginGroup>
  </pluginGroups>
</settings>

Then, because the plugin name matches the ${prefix}-maven-plugin or maven-${prefix}-plugin patterns, you could execute:

mvn touch:timestamp 

Following the convention is recommended but, as I said, the prefix can also be configured.

How can I see if this goal exists?

Check the plugin documentation (derived from the plugin sources) or the plugin sources.


1 Note that there is also a typo at the bottom of the mentioned page of the Maven Book. The way to execute the plugin with a custom prefix should be mvn blah:echo (see MVNREF-145).

Pascal Thivent