How does the Maven plugin prefix work? Why does this allow a “search” but not a “berth”?

I tested using Maven and realized that I could fulfill the findbugs goal of the findbugs plugin without adding the plugin to the POM file. On the other hand, when I needed to run the runty target of the Jetty plugin, I was forced to add the plugin to the POM file or build failure.

  • Why did Jetty need to be configured in POM and Findbugs not?
  • How does Maven know which Findbugs should run (suppose we have plugins with the same name but with a different group identifier)?

When I run the first command, the assembly was completed without changes in the POM file:

 mvn findbugs:findbugs [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building module-mytest 1.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- findbugs-maven-plugin:3.0.4:findbugs (default-cli) @ module-mytest --- [INFO] Fork Value is true [java] Warnings generated: 6 [INFO] Done FindBugs Analysis.... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 24.165s [INFO] Finished at: Sun Oct 23 18:40:26 WEST 2016 [INFO] Final Memory: 21M/111M [INFO] ----------------------------------------------------------------------- 

But when I run the second, I get the following:

 mvn jetty:run [INFO] Scanning for projects... Downloading: http://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml Downloading: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml Downloaded: http://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml (13 KB at 30.0 KB/sec) Downloaded: http://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml (20 KB at 41.0 KB/sec) [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.129s [INFO] Finished at: Sun Oct 23 18:43:27 WEST 2016 [INFO] Final Memory: 12M/104M [INFO] ------------------------------------------------------------------------ [ERROR] No plugin found for prefix 'jetty' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/home/hp-pc/.m2/repository), central (http://repo.maven.apache.org/maven2)] -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/NoPluginFoundForPrefixException 

So, in order to transfer the assembly, I needed to add the following to the pom file:

 <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.11.v20150529</version> </plugin> 
+7
java maven maven-metadata
source share
1 answer

What is a prefix and why do we need it?

You have just encountered Maven Plugin Resolution Prefix . This is a function that allows the user to call the targets of a specific Maven plugin using its prefix. When you invoke the target directly on the command line, you can use the fully functional form:

 mvn my.plugin.groupId:foo-maven-plugin:1.0.0:bar 

This will call the bar target of the Foo Maven plugin with the coordinates my.plugin.groupId:foo-maven-plugin:1.0.0 (in the form of groupId:artifactId:version ). It works well, but it is a bit detailed. It would be nice to resort to this goal in a simpler way without specifying all of these coordinates. Maven makes this possible by assigning prefixes to plugins, so you can refer to this prefix instead of integer coordinates:

 mvn foo:bar ^^^ ^^^ | | prefix | | goal 

How is this prefix defined?

You can define a prefix for each Maven plugin. This corresponds to the simple name used to identify it:

Traditional artifact identifier formats for use are:

  • maven-${prefix}-plugin - for official plugins supported by the Apache Maven team itself (you should not use this naming pattern for your plugin, see this note for more information).
  • ${prefix}-maven-plugin - for plugins from other sources

If your artifactId plugin matches this pattern, Maven automatically matches your plugin with the correct prefix in the metadata stored in your plugin groupId path in the repository.

In other words, if your plugin artifact identifier is named foo-maven-plugin , Maven will automatically assign it the prefix foo . If you do not want this destination by default, you can configure your own using maven-plugin-plugin and its goalPrefix .

How are Maven map prefixes for plugins?

In a team

 mvn foo:bar 

Maven should have a way to conclude that foo actually means my.plugin.groupId:foo-maven-plugin . In the settings.xml file you can add groups of plugins in the form:

 <pluginGroups> <pluginGroup>org.mortbay.jetty</pluginGroup> </pluginGroups> 

What this means, says Maven, which group identifier should he consider when you use the prefix in the command. By default and in addition to the groups specified in the settings, Maven also searches for group identifiers org.apache.maven.plugins and org.codehaus.mojo . It performs a default search after the ones you configured in the settings. Therefore, with the above configuration and the mvn foo:bar command, Maven will look for the plugin with the foo prefix inside the id group org.mortbay.jetty , org.apache.maven.plugins and org.codehaus.mojo .

The second step is how this search is actually performed. Maven will download metadata files (or view them in your local repository, if they are already loaded), called maven-metadata.xml , from each remote repository in these group identifiers. If we take an example where the only remote repository we have is Maven Central, Maven will first download http://repo1.maven.org/maven2/org/mortbay/jetty/maven-metadata.xml and look inside this file if we have something that displays foo . Notice how the group identifier was converted to a directory structure in the remote repository. The structure of this metadata file is:

 <metadata> <plugins> <plugin> <name>Some Awesome Maven Plugin</name> <prefix>somePrefix</prefix> <artifactId>some-maven-plugin</artifactId> </plugin> </plugins> </metadata> 

If none of the <plugin> sections contains a <prefix> that matches the one we specified ( foo ), Maven will continue the next group identifier by clicking <code> http://repo1.maven.org/maven2/org/codehaus/mojo /maven-metadata.xmlcode> . Again, if none are found, Maven will finally hit http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml (note the Downloading: logs in mvn jetty:run , just getting these last two files). If none of them are found, Maven can do nothing else for you, and this will be an error:

[ERROR] The plugin was not found for the prefix 'foo' in the current project and in the plugin groups [org.mortbay.jetty, org.apache.maven.plugins, org.codehaus.mojo] accessible from the repositories [local (... / . m2 / repository), central ( http://repo.maven.apache.org/maven2)] → [Help 1]

This is the mistake you have here. However, if one match was made during this search, then Maven can use <artifactId> to use.

Now this means that it has a group identifier and an artifact identifier. The final piece of the puzzle is the version

Which version will be used?

Maven will use the latest available if it is not explicitly configured in the POM (see the next section). All possible versions are extracted by extracting another metadata file, which is still called maven-metadata.xml , but this time it lives with the artifact identifier folder in the repository (unlike above, where it was next to the group identifier). Taking the Maven Clean plugin example (the group ID and artifact ID will be found with the above mechanism and the mvn clean:clean command), maven-metadata.xml looks like this:

 <metadata> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-clean-plugin</artifactId> <versioning> <latest>3.0.0</latest> <release>3.0.0</release> <versions> <version>2.0-beta-1</version> <version>2.0-rc1</version> <version>2.0</version> <version>2.1</version> <!-- more versions --> <version>3.0.0</version> </versions> <lastUpdated>20151022205339</lastUpdated> </versioning> </metadata> 

Maven will select the version of <release> as the version, which is the latest version of the plugin version. If this tag is not present, it will select <latest> , which are the latest version of the plugin, release, or snapshot. It may happen that there are no both tags, in which case Maven will choose the first version or the first snapshot due to the lack of release , a list of <version> elements.

If this still fails, Maven can do nothing else for you, the version cannot be displayed, and these are errors. However, this is unlikely to happen. Now we have collected the group identifier, artifact identifier and version; to finally call the bar target of our plugin.

What is the problem with my configuration?

As mentioned above, Maven looks at certain predefined group identifiers within active remote repositories to look for matches with a given prefix. Using command

 mvn findbugs:findbugs 

Maven starts a search with the findbugs prefix. Since our configuration does not have a <pluginGroup> in our settings, Maven looks at the group identifier org.codehaus.mojo and org.apache.maven.plugins to match the prefix.

And he finds one: Findbugs Maven Plugin is published under the group ID org.codehaus.mojo ; indeed, you can find in maven-metadata.xml :

 <plugin> <name>FindBugs Maven Plugin</name> <prefix>findbugs</prefix> <artifactId>findbugs-maven-plugin</artifactId> </plugin> 

And you can also find the version that will be used by looking at the maven-metadata.xml file in findbugs-maven-plugin just displayed (3.0.4 at the time of this writing and note how it exactly matches the version in mvn findbugs:findbugs your question). So the permission succeeded, and then Maven can continue to refer to findbugs target of this plugin.

The second example is the command

 mvn jetty:run 

As before, the same resolution steps occur, but in this case you will find that the <jetty> prefix is ​​not displayed in any of the maven-metadata.xml for the id group org.codehaus.mojo and org.apache.maven.plugins , Thus, the permission fails, and Maven returns the error that you have.

But we saw how to make it work! We can add <pluginGroup> inside our settings so that this group identifier can also be searched at the time of resolution. Jetty Maven Plugin is published under the id group org.eclipse.jetty , and if we look at the corresponding maven-metadata.xml in Maven Central , you will see that there is <prefix>jetty</prefix> . So the fix is ​​simple: just define this new group id to search inside the settings:

 <pluginGroups> <pluginGroup>org.eclipse.jetty</pluginGroup> </pluginGroups> 

Now, Maven will also consider this group identifier and successfully combine the jetty prefix with org.eclipse.jetty:jetty-maven-plugin .

How can I use a specific version? Or I do not want to change my settings!

Of course, all this permission can be tracked if you clearly define the plugin in your POM, and this is another solution that you found:

 <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.11.v20150529</version> </plugin> 

and use

 mvn jetty:run 

If you configure the plugin directly in the POM, prefix resolution still occurs, but it is slightly masked: Maven will download the plugin from the configured remote repositories and will download and install all metadata files along this path, including maven-metadata.xml containing the jetty prefix jetty . Since it automatically loads it, a search is always performed.

Note also that since the plugin was defined in POM, you do not need <pluginGroup> in the settings: the group ID was recorded in POM. In addition, it ensures that version 9.2.11.v20150529 is used, not the latest.

+16
source share

All Articles