java - migrar - maven central
¿Cómo funciona la resolución del prefijo del complemento Maven? ¿Por qué está resolviendo "findbugs" pero no "embarcadero"? (1)
Estaba haciendo algunas pruebas con Maven y me di cuenta de que puedo ejecutar el objetivo findbugs del complemento Findbugs sin agregar el complemento al archivo POM.
Por otro lado, cuando necesitaba ejecutar el objetivo de
run
del complemento Jetty, me vi obligado a agregar el complemento al archivo POM o la compilació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 que agregar complementos con el mismo nombre pero con una identificación de grupo diferente)?
Cuando ejecuto el primer comando, la compilación es exitosa 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 ejecuto el segundo me sale 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 compilación, necesitaba agregar lo siguiente al archivo pom:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.11.v20150529</version>
</plugin>
¿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 objetivos de un complemento Maven específico, utilizando su prefijo. Cuando invocas directamente un objetivo 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 objetivos 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 objetivo de una manera más simple, sin especificar todas esas coordenadas.
Maven hace esto posible mediante la asignación de prefijos a complementos, para que pueda 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 complemento Maven. Esto corresponde a un nombre simple utilizado para identificarlo:
Los formatos de ID de artefactos convencionales para usar son:
maven-${prefix}-plugin
- para complementos oficiales mantenidos por el equipo de Apache Maven (no debe usar este patrón de nombres para su complemento, consulte esta nota para obtener más información)${prefix}-maven-plugin
- para complementos de otras fuentesSi el artifactId de su complemento se ajusta a este patrón, Maven asignará automáticamente su complemento al prefijo correcto en los metadatos almacenados dentro de la ruta groupId de su complemento en el repositorio.
Dicho de otra manera, si la identificación del artefacto de su complemento se llama
foo-maven-plugin
, Maven le asignará automáticamente un prefijo
foo
.
Si no desea esta asignación predeterminada, aún puede configurar la suya con la ayuda de
maven-plugin-plugin
y su parámetro
goalPrefix
.
¿Cómo asigna Maven 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:
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
Lo que esto hace es decirle a Maven qué ID de grupo se supone que debe considerar 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 identificadores de grupo
org.apache.maven.plugins
y
org.codehaus.mojo
.
Busca los 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 repositorio local si ya están descargados), llamados
maven-metadata.xml
, de cada repositorio remoto en esos identificadores de grupo.
Si tomamos el ejemplo donde el único repositorio 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 mapeo
foo
.
Observe cómo la identificación del grupo se transformó en una estructura de directorio en el repositorio remoto.
La estructura de este archivo de metadatos es:
<metadata>
<plugins>
<plugin>
<name>Some Awesome Maven Plugin</name>
<prefix>somePrefix</prefix>
<artifactId>some-maven-plugin</artifactId>
</plugin>
</plugins>
</metadata>
Si ninguna de la sección
<plugin>
contiene un
<prefix>
que sea igual al que especificamos (
foo
), Maven continuará con la siguiente identificación de grupo, presionando
http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml
.
Una vez más, si no se encuentra ninguno, Maven finalmente presionará
http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml
(observe la
Downloading:
registra en su
mvn jetty:run
, buscar exactamente esos dos últimos archivos).
Si todavía no se encuentra ninguno, ya no hay nada que Maven pueda hacer por usted, y se producirá 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 repositorios [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, Maven puede deducir el
<artifactId>
para usar.
Ahora significa que tiene la identificación del grupo y la identificación del artefacto. La pieza final del rompecabezas es la versión.
¿Qué versión se va a usar?
Maven tomará la última disponible, a menos que se configure explícitamente en el POM (consulte la siguiente sección).
Todas las versiones posibles se recuperan recuperando otro archivo de metadatos, todavía llamado
maven-metadata.xml
, pero esta vez viviendo junto a la carpeta de identificación de artefactos en el repositorio (al contrario de los anteriores, donde estaba junto a la identificación del grupo).
Tomando el ejemplo del complemento Maven Clean (cuya identificación de grupo e identificación de artefacto se encontraría con el mecanismo anterior y un comando de
mvn clean:clean
), el
maven-metadata.xml
ve así:
<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
seleccionará como versión
la
versión
<release>
, que representa la última versión de lanzamiento del complemento.
Si esa etiqueta no está allí, seleccionará
<latest>
que representa la última versión del complemento, lanzamiento o instantánea.
Puede suceder que ambas etiquetas 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
<version>
.
Si eso todavía falla, ya no hay nada que Maven pueda hacer por usted, no se puede deducir la versión y se produce un error.
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;
hora de invocar finalmente el objetivo 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 repositorios 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
<pluginGroup>
en nuestra configuración, Maven busca la
org.codehaus.mojo
grupo
org.codehaus.mojo
y
org.apache.maven.plugins
para una coincidencia de prefijo.
Y sí encuentra uno:
Findbugs Maven Plugin
se publica bajo la
org.codehaus.mojo
grupo
org.codehaus.mojo
;
de hecho, puedes encontrarlo
http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml
:
<plugin>
<name>FindBugs Maven Plugin</name>
<prefix>findbugs</prefix>
<artifactId>findbugs-maven-plugin</artifactId>
</plugin>
Y también puede encontrar la versión que se utilizará al mirar en el archivo
maven-metadata.xml
bajo
findbugs-maven-plugin
acaba de deducir (3.0.4 al momento de escribir esto; y observe cómo coincide exactamente con el versión en
mvn findbugs:findbugs
registros de
mvn findbugs:findbugs
de su pregunta).
Entonces la resolución tuvo éxito, y luego Maven puede continuar invocando el objetivo
findbugs
de este complemento.
El segundo ejemplo es el comando
mvn jetty:run
Como antes, ocurren los mismos pasos de resolución, pero, en este caso, descubrirá que el prefijo
<jetty>
no aparece en ninguno de los
maven-metadata.xml
para los identificadores de grupo
org.codehaus.mojo
y
org.apache.maven.plugins
.
Entonces la resolución falla y Maven le devuelve el error que tiene.
¡Pero hemos visto cómo hacerlo funcionar!
Podemos agregar un
<pluginGroup>
dentro de nuestra configuración, para que esta identificación de grupo también se pueda buscar durante la resolución.
El
complemento Jetty Maven
se publica bajo la identificación de grupo
org.eclipse.jetty
, y si miramos el
maven-metadata.xml
correspondiente
en Maven Central
, verá que
<prefix>jetty</prefix>
está allí.
Entonces, la solución es simple: solo defina esta nueva identificación de grupo para buscar dentro de la configuración:
<pluginGroups>
<pluginGroup>org.eclipse.jetty</pluginGroup>
</pluginGroups>
Ahora, Maven también buscará en esta identificación de 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 no quiero modificar mi configuración!
Por supuesto, toda esta resolución se puede desviar si define el complemento explícitamente en su POM, que es la otra solución que encontró:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.2.11.v20150529</version>
</plugin>
y use
mvn jetty:run
Si configura el complemento directamente en el POM, la resolución del prefijo aún se produce, pero está un poco enmascarada: Maven descargará el complemento desde los repositorios 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 lo 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
<pluginGroup>
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.