¿Cómo funciona la resolución de prefijo Maven plugin? ¿Por qué está resolviendo “findbugs” pero no “embarcadero”?

Estaba haciendo algunas pruebas con Maven y me di cuenta de que puedo ejecutar el objective de Findbugs del complemento Findbugs sin agregar el complemento al archivo POM. Por otro lado, cuando tuve que ejecutar el objective de run del plugin Jetty, me vi obligado a agregar el complemento al archivo POM o la construcción falló.

  • ¿Por qué Jetty necesitaba configuración en el POM mientras que Findbugs no?
  • ¿Cómo sabe Maven qué Findbugs ejecutar (supongamos que tenemos plugins con el mismo nombre pero diferente ID de grupo)?

Cuando ejecuto el primer comando, la comstackción tiene éxito sin ningún cambio en el archivo POM:

 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] ----------------------------------------------------------------------- 

Pero cuando corro el segundo, entiendo esto:

 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 

Entonces, para pasar la comstackción, necesitaba agregar lo siguiente al archivo pom:

  org.eclipse.jetty jetty-maven-plugin 9.2.11.v20150529  

¿Qué es un prefijo y por qué lo necesitamos?

Acabas de encontrar la resolución de prefijo de complemento de Maven. Esta es una característica que permite al usuario invocar objectives de un plugin Maven específico, usando su prefijo. Cuando invocas directamente un objective en la línea de comandos, puedes usar la forma completa de:

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

Esto invocaría la bar de objectives del complemento Foo Maven que tiene las coordenadas my.plugin.groupId:foo-maven-plugin:1.0.0 (en forma de groupId:artifactId:version ). Funciona bien, pero es un poco detallado. Sería bueno invocar este objective de una manera más simple, sin especificar todas esas coordenadas. Maven lo hace posible asignando prefijos a los complementos, de modo que puede referirse a este prefijo en lugar de las coordenadas completas, con:

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

¿Cómo se determina este prefijo?

Puede definir un prefijo para cada plugin de Maven. Esto corresponde a un nombre simple usado para identificarlo:

Los formatos de identificación de artefactos convencionales a utilizar son:

  • maven-${prefix}-plugin – para complementos oficiales mantenidos por el propio equipo de Apache Maven (no debe usar este patrón de nomenclatura para su complemento, consulte esta nota para obtener más información)
  • ${prefix}-maven-plugin – para complementos de otras fonts

Si el artifactId de su plugin se ajusta a este patrón, Maven automáticamente mapeará su plugin al prefijo correcto en los metadatos almacenados dentro de la ruta groupId de su plugin en el repository.

Dicho de otra manera, si el id del artefacto de su complemento se llama foo-maven-plugin , Maven lo asignará automáticamente un prefijo de foo . Si no desea esta asignación predeterminada, puede configurar la suya con la ayuda de maven-plugin-plugin y su parámetro goalPrefix .

¿Cómo mapea el mapa los prefijos a los complementos?

En el comando

 mvn foo:bar 

Maven debe tener una manera de deducir que foo realmente significa my.plugin.groupId:foo-maven-plugin . En el archivo settings.xml , puede agregar grupos de complementos , en forma de:

  org.mortbay.jetty  

Lo que hace esto es decirle a Maven qué ID de grupo se supone que debe tener en cuenta cuando usa un prefijo en un comando. De forma predeterminada, y además de los grupos especificados en la configuración, Maven también busca los org.codehaus.mojo grupo org.apache.maven.plugins y org.codehaus.mojo . Busca aquellos predeterminados después de los que configuró en la configuración. Por lo tanto, con la configuración anterior, y un comando de mvn foo:bar , Maven buscará un complemento que tenga un prefijo de foo dentro del grupo id org.mortbay.jetty , org.apache.maven.plugins y org.codehaus.mojo .

El segundo paso es cómo se realiza esa búsqueda. Maven descargará archivos de metadatos (o los buscará en su repository local si ya están descargados), llamados maven-metadata.xml , desde cada repository remoto en esos ID de grupo. Si tomamos el ejemplo de que el único repository remoto que tenemos es Maven Central, Maven primero descargará http://repo1.maven.org/maven2/org/mortbay/jetty/maven-metadata.xml , y mirará dentro de este archivo si tenemos algo mapeando foo . Observe cómo la identificación del grupo se transformó en una estructura de directorio en el repository remoto. La estructura de este archivo de metadatos es:

    Some Awesome Maven Plugin somePrefix some-maven-plugin    

Si ninguna parte de la sección contiene un

que sea igual al que hemos especificado ( foo ), Maven continuará con la siguiente identificación de grupo, presionando http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml . De nuevo, si no se encuentra ninguno, Maven finalmente llegará a http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml (observe la Downloading: registros en su mvn jetty:run , buscando exactamente esos dos últimos archivos). Si aún no se encuentra ninguno, ya no hay nada que Maven pueda hacer por usted, y será un error:

[ERROR] No se encontró ningún complemento para el prefijo ‘foo’ en el proyecto actual y en los grupos de complementos [org.mortbay.jetty, org.apache.maven.plugins, org.codehaus.mojo] disponibles en los repositorys [local (.. ./.m2/repository), central ( http://repo.maven.apache.org/maven2)] -> [Ayuda 1]

Este es el error que tienes aquí. Sin embargo, si se hizo una coincidencia durante esta búsqueda, entonces Maven puede deducir el para usar.

Ahora significa que tiene la identificación del grupo y la identificación del artefacto. La última pieza del rompecabezas es la versión

¿Qué versión va a usarse?

Maven tomará el último disponible, a menos que esté configurado explícitamente en el POM (consulte la siguiente sección). Todas las versiones posibles se recuperan obteniendo otro archivo de metadatos, todavía llamado maven-metadata.xml , pero esta vez viviendo junto a la carpeta id del artefacto en el repository (a diferencia de los anteriores, donde estaba junto a la identificación del grupo). Tomando el ejemplo del plugin Maven Clean (cuyo ID de grupo y artefacto se encontraría con el mecanismo anterior y un comando de mvn clean:clean ), maven-metadata.xml ve así:

  org.apache.maven.plugins maven-clean-plugin  3.0.0 3.0.0  2.0-beta-1 2.0-rc1 2.0 2.1  3.0.0  20151022205339   

Maven seleccionará como versión la , que representa la última versión de lanzamiento del complemento. Si esa etiqueta no está allí, seleccionará que representa la última versión del complemento, lanzamiento o instantánea. Puede suceder que ambas tags no estén allí, en cuyo caso, Maven seleccionará la primera versión, o la primera instantánea por falta de una versión , de la lista de elementos .

Si eso aún falla, ya no hay nada que Maven pueda hacer por usted, la versión no se puede deducir y tiene errores. Sin embargo, esto no es muy probable que suceda. Ahora hemos reunido la identificación del grupo, la identificación del artefacto y la versión; tiempo para invocar finalmente el objective de la bar de nuestro complemento.

¿Cuál es el problema con mi configuración?

Como se dijo anteriormente, Maven busca en ciertos identificadores de grupo predefinidos dentro de los repositorys remotos activos para buscar coincidencias con un prefijo dado. Con el comando

 mvn findbugs:findbugs 

Maven comienza la búsqueda con el prefijo findbugs . Dado que nuestra configuración no tiene ningún en nuestra configuración, Maven busca en org.codehaus.mojo y org.apache.maven.plugins ID de grupo para una coincidencia de prefijo.

Y encuentra uno: Findbugs Maven Plugin se publica bajo el id del grupo org.codehaus.mojo ; de hecho, puedes encontrarlo en maven-metadata.xml :

  FindBugs Maven Plugin findbugs findbugs-maven-plugin  

Y también puede encontrar la versión que se va a usar echando un vistazo al archivo maven-metadata.xml bajo el findbugs-maven-plugin recién deducido (3.0.4 en el momento de escribir esto, y observe cómo coincide exactamente con el versión en mvn findbugs:findbugs logs de su pregunta). Así que la resolución tuvo éxito, y luego Maven puede seguir findbugs objective findbugs de este complemento.

El segundo ejemplo es el comando

 mvn jetty:run 

Al igual que antes, ocurren los mismos pasos de resolución, pero, en este caso, descubrirá que el prefijo no aparece en ninguno de los maven-metadata.xml para el grupo ids org.codehaus.mojo y org.apache.maven.plugins . Entonces la resolución falla, y Maven devuelve el error que tienes.

¡Pero hemos visto cómo hacerlo funcionar! Podemos agregar un dentro de nuestra configuración, para que esta identificación de grupo también se pueda buscar durante la resolución. El plugin Jetty Maven se publica bajo el grupo id org.eclipse.jetty , y si echamos un vistazo al maven-metadata.xml correspondiente en Maven Central , verá que

jetty está allí. Entonces, la solución es simple: simplemente defina esta nueva identificación de grupo para buscar dentro de la configuración:

  org.eclipse.jetty  

Ahora, Maven también investigará la ID de este grupo y hará coincidir el prefijo del jetty con el org.eclipse.jetty:jetty-maven-plugin éxito.

¿Cómo puedo usar una versión específica? O bien, no quiero modificar mi configuración!

Por supuesto, toda esta resolución se puede rastrear si defines explícitamente el complemento en tu POM, que es la otra solución que encontraste:

  org.eclipse.jetty jetty-maven-plugin 9.2.11.v20150529  

y use

 mvn jetty:run 

Si configura el complemento directamente en el POM, la resolución del prefijo aún ocurre, pero está un poco enmascarada: Maven descargará el complemento de los repositorys remotos configurados y descargará e instalará todos los archivos de metadatos a lo largo del camino, incluido el maven-metadata.xml contiene la asignación para el jetty prefijo. Entonces, dado que se descarga automáticamente, la búsqueda siempre tiene éxito.

Tenga en cuenta también que dado que el complemento se definió en el POM, no necesitaría ningún en la configuración: la identificación del grupo se escribió en el POM. Además, se asegura de que se utilizará la versión 9.2.11.v20150529, en lugar de la última.