{"id":7281,"date":"2025-11-13T13:34:22","date_gmt":"2025-11-13T12:34:22","guid":{"rendered":"https:\/\/www.hostingtg.com\/blog\/?p=7281"},"modified":"2025-11-13T13:34:26","modified_gmt":"2025-11-13T12:34:26","slug":"maven","status":"publish","type":"post","link":"https:\/\/www.hostingtg.com\/blog\/maven\/","title":{"rendered":"Maven: gu\u00eda pr\u00e1ctica de comandos, ciclo de vida y pom.xml"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Qu\u00e9 es Apache Maven<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Maven es uno de esos veteranos que no pasan de moda. En mi d\u00eda a d\u00eda, siempre me ha dado la sensaci\u00f3n de ser ese \u201cviejo conocido\u201d del <strong>ecosistema Java<\/strong>: quiz\u00e1 no sea la herramienta m\u00e1s moderna del momento, pero sigue siendo la columna vertebral de much\u00edsimos proyectos serios en producci\u00f3n. \u00bfPor qu\u00e9? Porque resuelve de forma coherente tres problemas que, combinados, son el 80% del \u201cbuild pain\u201d en equipos <a href=\"https:\/\/www.hostingtg.com\/blog\/hola-mundo-en-java\/\">Java<\/a>: gesti\u00f3n de dependencias, estructura del proyecto y ciclo de vida de construcci\u00f3n.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Maven no solo compila c\u00f3digo<\/strong>: impone orden. Te propone convenciones (estructura de carpetas, fases de build, naming) y, a cambio, te ofrece un proceso predecible de principio a fin. Esa previsibilidad es oro cuando trabajas en equipos grandes o en proyectos que est\u00e1n destinados a vivir a\u00f1os. No est\u00e1s inventando el build de cero; est\u00e1s aline\u00e1ndote con un est\u00e1ndar que miles de equipos ya han puesto a prueba.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Adem\u00e1s, el ecosistema que lo rodea es gigantesco: <a href=\"https:\/\/maven.apache.org\/\" target=\"_blank\" rel=\"noopener\">repositorios remotos p\u00fablicos y privados<\/a>, un cat\u00e1logo inmenso de plugins, tooling maduro en IDEs y CI\/CD, y toneladas de documentaci\u00f3n. \u00bfEs perfecto? No. El XML es verboso y, cuando te sales del camino feliz, la curva de aprendizaje se nota. Pero si tu objetivo es tener un build estable, auditable y no reinventar la rueda, Maven sigue siendo una apuesta segura.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">La filosof\u00eda de \u201corden y previsibilidad\u201d<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">La promesa de <strong>Maven es simple<\/strong>: si sigues sus convenciones, obtienes predictibilidad. El ciclo de vida est\u00e1 definido, las carpetas tienen significado, y las fases encadenan tasks en un orden conocido. Cuando entiendes esa filosof\u00eda, el \u201ctanto XML\u201d deja de ser ruido y empieza a ser un contrato expl\u00edcito de c\u00f3mo se construye tu software.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Maven vs otras herramientas (cu\u00e1ndo elegirlo)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Elige Maven si\u2026<\/strong> valoras la estabilidad, tienes m\u00faltiples equipos, quieres auditar el build y te favorecen las convenciones fuertes.<\/li>\n\n\n\n<li><strong>Elige otra herramienta si\u2026<\/strong> priorizas DSLs m\u00e1s concisos y builds muy din\u00e1micos, o si necesitas mucha metaprogramaci\u00f3n en el proceso.<br>En mi experiencia, cuando el proyecto crecer\u00e1 y habr\u00e1 rotaci\u00f3n de personas, el \u201corden maveniano\u201d te ahorra discusiones y sorpresas.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Ciclo de vida de Maven, fases y goals (con mentalidad pr\u00e1ctica)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Maven define <strong>ciclos de vida<\/strong> y <strong>fases<\/strong>. Piensa en el ciclo de vida como una lista ordenada; cada fase invoca goals de plugins. El ciclo de vida \u201cdefault\u201d (build) es el m\u00e1s usado: <code>validate<\/code> \u2192 <code>compile<\/code> \u2192 <code>test<\/code> \u2192 <code>package<\/code> \u2192 <code>verify<\/code> \u2192 <code>install<\/code> \u2192 <code>deploy<\/code>. Si ejecutas <code>mvn package<\/code>, Maven ejecuta tambi\u00e9n todas las fases previas necesarias. Esta cadena de responsabilidades es la que aporta esa sensaci\u00f3n de \u201ctodo encaja\u201d.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Las <strong>fases clave<\/strong> en el d\u00eda a d\u00eda:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>clean<\/code>: limpia el <code>target\/<\/code>. Suelo invocarla antes de un build \u201cserio\u201d.<\/li>\n\n\n\n<li><code>compile<\/code>: compila el c\u00f3digo fuente principal.<\/li>\n\n\n\n<li><code>test<\/code>: ejecuta tests unitarios (Surefire).<\/li>\n\n\n\n<li><code>package<\/code>: empaqueta (JAR\/WAR\/\u2026).<\/li>\n\n\n\n<li><code>verify<\/code>: ejecuta verificaciones adicionales (calidad, integraci\u00f3n).<\/li>\n\n\n\n<li><code>install<\/code>: instala el artefacto en tu <strong>repositorio local<\/strong> (<code>~\/.m2\/repository<\/code>).<\/li>\n\n\n\n<li><code>deploy<\/code>: publica en un <strong>repositorio remoto<\/strong> (Nexus\/Artifactory).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Comandos comunes de uso diario<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>mvn clean install<\/code> para un ciclo \u201cde todo un poco\u201d.<\/li>\n\n\n\n<li><code>mvn -DskipTests package<\/code> cuando quieres empaquetar r\u00e1pido (ojo: \u00fasalo con criterio).<\/li>\n\n\n\n<li><code>mvn deploy -Prelease<\/code> con un perfil de publicaci\u00f3n.<\/li>\n\n\n\n<li><code>mvn test -T 4<\/code> para paralelizar (si tu proyecto lo permite).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En mi caso, lo que m\u00e1s valoro de esta mec\u00e1nica es que, una vez acuerdas con el equipo \u201cqu\u00e9 se ejecuta en cada fase\u201d, el build deja de ser un misterio. \u201cCuando entiendes su filosof\u00eda, todo tiene m\u00e1s sentido\u201d: fases bien definidas, plugins espec\u00edficos y resultados repetibles.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>clean<\/code>, <code>default\/build<\/code>, <code>site<\/code>: qu\u00e9 ejecuta cada uno<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>clean<\/strong>: ciclo dedicado a limpiar.<\/li>\n\n\n\n<li><strong>default\/build<\/strong>: el que compila, testea, empaqueta y publica.<\/li>\n\n\n\n<li><strong>site<\/strong>: genera documentaci\u00f3n del proyecto (reports, javadocs, etc.).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Comandos de uso diario<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Compilar y probar<\/strong>: <code>mvn clean test<\/code><\/li>\n\n\n\n<li><strong>Empaquetar<\/strong>: <code>mvn package<\/code><\/li>\n\n\n\n<li><strong>Instalar en local<\/strong>: <code>mvn install<\/code><\/li>\n\n\n\n<li><strong>Publicar<\/strong>: <code>mvn deploy<\/code> (con credenciales y repos configurados)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">POM en profundidad: la \u201cradiograf\u00eda\u201d del proyecto<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Para m\u00ed, el <code>pom.xml<\/code> es como la radiograf\u00eda del proyecto. Ah\u00ed declaras el <strong>parent<\/strong> (herencia), las <strong>dependencias<\/strong>, los <strong>plugins<\/strong> que ejecutar\u00e1n los goals, y los <strong>profiles<\/strong> que activan comportamientos por entorno. Puede parecer pesado al principio, pero tener toda la configuraci\u00f3n centralizada evita muchos quebraderos de cabeza con el paso del tiempo.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Estructura m\u00ednima y herencia (<code>parent<\/code>)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Una base m\u00ednima t\u00edpica:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;project>\n  &lt;modelVersion>4.0.0&lt;\/modelVersion>\n  &lt;groupId>com.ejemplo&lt;\/groupId>\n  &lt;artifactId>mi-app&lt;\/artifactId>\n  &lt;version>1.0.0&lt;\/version>\n  &lt;packaging>jar&lt;\/packaging>\n\n  &lt;parent>\n    &lt;groupId>org.springframework.boot&lt;\/groupId>\n    &lt;artifactId>spring-boot-starter-parent&lt;\/artifactId>\n    &lt;version>3.3.0&lt;\/version>\n  &lt;\/parent>\n&lt;\/project>\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">El <strong>parent<\/strong> aporta versiones y configuraci\u00f3n por defecto (gesti\u00f3n centralizada). En proyectos multi-m\u00f3dulo, un POM padre define <code>modules<\/code>, versiones y pol\u00edticas de calidad; los subm\u00f3dulos heredan. Este patr\u00f3n reduce la duplicidad y facilita upgrades controlados.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>dependencyManagement<\/code> y uso de BOMs<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>dependencyManagement<\/code> fija <strong>versiones<\/strong> sin forzarlas autom\u00e1ticamente como dependencias. As\u00ed evitas \u201cchoques\u201d de versiones. Los <strong>BOMs<\/strong> (Bill of Materials) te permiten importar un conjunto coherente de versiones (por ejemplo, de Spring).<br>Ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;dependencyManagement>\n  &lt;dependencies>\n    &lt;dependency>\n      &lt;groupId>org.springframework.boot&lt;\/groupId>\n      &lt;artifactId>spring-boot-dependencies&lt;\/artifactId>\n      &lt;version>3.3.0&lt;\/version>\n      &lt;type>pom&lt;\/type>\n      &lt;scope>import&lt;\/scope>\n    &lt;\/dependency>\n  &lt;\/dependencies>\n&lt;\/dependencyManagement>\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Luego, en tus dependencias, omites las versiones y heredas las del BOM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Perfiles (<code>profiles<\/code>) y propiedades (<code>-D<\/code>)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Los perfiles activan configuraciones condicionales (por ejemplo, endpoints de repos o flags para CI).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;profiles>\n  &lt;profile>\n    &lt;id>ci&lt;\/id>\n    &lt;properties>\n      &lt;skipITs>true&lt;\/skipITs>\n    &lt;\/properties>\n    &lt;activation>\n      &lt;property>\n        &lt;name>env.CI&lt;\/name>\n      &lt;\/property>\n    &lt;\/activation>\n  &lt;\/profile>\n&lt;\/profiles>\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Puedes activar con <code>-Pci<\/code> o por variables de entorno. Tambi\u00e9n es com\u00fan pasar propiedades con <code>-Dclave=valor<\/code> (por ejemplo, <code>-DskipTests<\/code>).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Gesti\u00f3n de dependencias sin dolor<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La gesti\u00f3n de dependencias es, probablemente, la comodidad que m\u00e1s valoro: dejar de perseguir JARs a mano y confiar en repositorios remotos es un antes y un despu\u00e9s. Pero no todo es autom\u00e1tico: hay que <strong>diagnosticar conflictos<\/strong>, <strong>fijar versiones<\/strong> y <strong>garantizar reproducibilidad<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>dependency:tree<\/code> y resoluci\u00f3n de conflictos<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Empieza por:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mvn dependency:tree -Dincludes=grupo:artefacto\nmvn dependency:tree -Dverbose\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Con esto identificas <strong>dependencias transitivas<\/strong> que traen versiones no deseadas. Si dos librer\u00edas arrastran versiones distintas de la misma dependencia, define tu versi\u00f3n \u201cfuente de verdad\u201d en <code>dependencyManagement<\/code>. Si el conflicto persiste, puedes <strong>excluir<\/strong> la transitiva problem\u00e1tica:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;dependency>\n  &lt;groupId>a&lt;\/groupId>\n  &lt;artifactId>b&lt;\/artifactId>\n  &lt;version>1.2.3&lt;\/version>\n  &lt;exclusions>\n    &lt;exclusion>\n      &lt;groupId>x&lt;\/groupId>\n      &lt;artifactId>y&lt;\/artifactId>\n    &lt;\/exclusion>\n  &lt;\/exclusions>\n&lt;\/dependency>\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Estrategias para reproducibilidad<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Versiones fijas<\/strong> (evita <code>LATEST<\/code>\/<code>RELEASE<\/code> y rangos muy abiertos).<\/li>\n\n\n\n<li><strong>BOMs<\/strong> para coherencia global.<\/li>\n\n\n\n<li><strong>Bloqueo de repos<\/strong> y uso de <strong>mirrors<\/strong> confiables.<\/li>\n\n\n\n<li><strong>Cacheo en CI<\/strong> del repositorio local (<code>~\/.m2\/repository<\/code>) con claves de cach\u00e9 sensatas (hash del <code>pom.xml<\/code>\/lockfiles).<\/li>\n\n\n\n<li><strong>build en batch<\/strong> (<code>-B<\/code>) y <strong>paralelismo controlado<\/strong> (<code>-T<\/code>) para tiempos estables.<\/li>\n\n\n\n<li>Revisa el <strong>effective POM<\/strong> (<code>mvn help:effective-pom<\/code>) para confirmar qu\u00e9 configuraci\u00f3n real se est\u00e1 aplicando.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Plugins que realmente usar\u00e1s<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">El cat\u00e1logo es inmenso, pero estos marcan la diferencia en la pr\u00e1ctica:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Testing: Surefire \/ Failsafe<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Surefire<\/strong> ejecuta <strong>tests unitarios<\/strong> (fase <code>test<\/code>).<\/li>\n\n\n\n<li><strong>Failsafe<\/strong> ejecuta <strong>tests de integraci\u00f3n<\/strong> (fase <code>verify<\/code>).<br>Esto te permite separar ritmos: r\u00e1pido en unitarias, m\u00e1s caro en integraci\u00f3n.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Empaquetado\/uberjar: Shade \/ Assembly<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Shade<\/strong> crea \u201cuberjars\u201d con dependencias incluidas; ideal para CLIs o microservicios empaquetables.<\/li>\n\n\n\n<li><strong>Assembly<\/strong> genera distribuciones personalizadas (zips con scripts, conf, etc.).<br>Consejo: al usar Shade, cuida el \u201crelocation\u201d de paquetes para evitar conflictos en runtime.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Calidad y versiones: JaCoCo, Versions, Spotless<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JaCoCo<\/strong> para cobertura (reportes fiables que puedes gatear en <code>verify<\/code>).<\/li>\n\n\n\n<li><strong>Versions<\/strong> te ayuda a <strong>descubrir updates<\/strong> seguros (<code>mvn versions:display-dependency-updates<\/code>).<\/li>\n\n\n\n<li><strong>Spotless<\/strong> estandariza el formato (menos \u201cdiff ruido\u201d en PRs).<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En proyectos reales, combinar estos plugins con perfiles por entorno (desarrollo\/CI\/release) te da un balance s\u00f3lido entre velocidad y calidad.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Maven en CI\/CD y grandes equipos<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Integrar Maven en CI\/CD es muy directo. Lo b\u00e1sico:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ejecuta en <strong>modo batch<\/strong> (<code>-B<\/code>) para evitar prompts.<\/li>\n\n\n\n<li>Usa <strong>cach\u00e9 del repositorio local<\/strong> para acelerar builds (pero inval\u00eddala cuando cambie tu <code>pom.xml<\/code>).<\/li>\n\n\n\n<li>Controla <strong>paralelismo<\/strong> (<code>-T 2C<\/code> \u2192 dos hilos por CPU) y mide antes\/despu\u00e9s.<\/li>\n\n\n\n<li>Separa <strong>pipelines<\/strong> para unitarias vs integraci\u00f3n.<\/li>\n\n\n\n<li>Publica artefactos con <strong>credenciales seguras<\/strong> y perfiles espec\u00edficos.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><code>settings.xml<\/code>: mirrors, <code>servers<\/code>, snapshots vs releases<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Tu <code>settings.xml<\/code> (global o de usuario) define credenciales y mirrors. Ejemplo m\u00ednimo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;settings>\n  &lt;servers>\n    &lt;server>\n      &lt;id>releases&lt;\/id>\n      &lt;username>${env.MVN_USER}&lt;\/username>\n      &lt;password>${env.MVN_PASS}&lt;\/password>\n    &lt;\/server>\n  &lt;\/servers>\n  &lt;mirrors>\n    &lt;mirror>\n      &lt;id>central-proxy&lt;\/id>\n      &lt;name>Company Proxy&lt;\/name>\n      &lt;url>https:\/\/nexus.miempresa.com\/repository\/maven-central\/&lt;\/url>\n      &lt;mirrorOf>central&lt;\/mirrorOf>\n    &lt;\/mirror>\n  &lt;\/mirrors>\n&lt;\/settings>\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Define <strong>repos snapshot<\/strong> y <strong>release<\/strong> por separado; configura el POM para que <code>deploy<\/code> use el <code>id<\/code> correcto. As\u00ed evitas publicar SNAPSHOTs en el sitio equivocado.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Nexus\/Artifactory: buenas pr\u00e1cticas<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un <strong>host \u00fanico<\/strong> para centralizar dependencias y publicar artefactos.<\/li>\n\n\n\n<li>Pol\u00edticas de <strong>retenci\u00f3n<\/strong> para SNAPSHOTs (no acumules basura).<\/li>\n\n\n\n<li>Roles\/Permisos claros: <code>deploy<\/code> \u2260 <code>admin<\/code>.<\/li>\n\n\n\n<li>Promoci\u00f3n de artefactos: SNAPSHOT \u2192 candidato \u2192 release con trazabilidad.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">En mi experiencia, esta disciplina hace que \u201clo predecible\u201d brille: el build se vuelve aburridamente confiable, que es lo mejor que puede ser.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Rendimiento y troubleshooting<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Optimizar Maven no es magia, es medici\u00f3n y peque\u00f1os ajustes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Flags \u00fatiles (<code>-X<\/code>, <code>-e<\/code>, <code>-U<\/code>)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>-X<\/code>: debug detallado (\u00fasalo con medida).<\/li>\n\n\n\n<li><code>-e<\/code>: stacktraces completos, \u00fatil para fallos raros.<\/li>\n\n\n\n<li><code>-U<\/code>: fuerza actualizaci\u00f3n de snapshots (no lo dejes por defecto en CI).<\/li>\n\n\n\n<li><code>-T<\/code>: paralelismo, mide primero (algunos plugins no son thread-safe).<\/li>\n\n\n\n<li><code>-DskipTests<\/code> \/ <code>-DskipITs<\/code>: acelera puntualmente, pero no lo conviertas en h\u00e1bito.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Errores comunes y c\u00f3mo evitarlos<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Conflictos de dependencias<\/strong>: soluciona en <code>dependencyManagement<\/code>; ap\u00f3yate en <code>dependency:tree<\/code>.<\/li>\n\n\n\n<li><strong>SNAPSHOTs en producci\u00f3n<\/strong>: proh\u00edbelos v\u00eda pol\u00edticas y perfiles.<\/li>\n\n\n\n<li><strong>Plugins viejos<\/strong>: revisa updates con <strong>Versions<\/strong>; anota versiones en el POM padre.<\/li>\n\n\n\n<li><strong>Builds no reproducibles<\/strong>: fija versiones, usa BOMs, bloquea mirrors y cachea correctamente.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Y, por supuesto, el cl\u00e1sico: \u201cel XML es verboso\u201d. S\u00ed, pero esa verbosidad deja todo expl\u00edcito y auditable. En mi caso, cuando necesito algo fuera de lo est\u00e1ndar, la curva existe, pero el resultado suele ser estable y documentado.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Cheatsheet final de comandos y flags<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Tarea<\/th><th>Comando<\/th><th>Notas<\/th><\/tr><\/thead><tbody><tr><td>Limpiar<\/td><td><code>mvn clean<\/code><\/td><td>Elimina <code>target\/<\/code><\/td><\/tr><tr><td>Compilar<\/td><td><code>mvn compile<\/code><\/td><td>C\u00f3digo principal<\/td><\/tr><tr><td>Test unitarios<\/td><td><code>mvn test<\/code><\/td><td>Surefire<\/td><\/tr><tr><td>Empaquetar<\/td><td><code>mvn package<\/code><\/td><td>JAR\/WAR\/\u2026<\/td><\/tr><tr><td>Instalar local<\/td><td><code>mvn install<\/code><\/td><td>A <code>~\/.m2\/repository<\/code><\/td><\/tr><tr><td>Publicar<\/td><td><code>mvn deploy<\/code><\/td><td>Repos remoto (settings)<\/td><\/tr><tr><td>Efective POM<\/td><td><code>mvn help:effective-pom<\/code><\/td><td>Diagn\u00f3stico<\/td><\/tr><tr><td>\u00c1rbol de deps<\/td><td><code>mvn dependency:tree<\/code><\/td><td>Conflictos<\/td><\/tr><tr><td>Saltar tests<\/td><td><code>mvn -DskipTests package<\/code><\/td><td>\u00dasalo con cabeza<\/td><\/tr><tr><td>Paralelismo<\/td><td><code>mvn -T 4 package<\/code><\/td><td>Mide compatibilidad<\/td><\/tr><tr><td>Debug<\/td><td><code>mvn -X \u2026<\/code><\/td><td>Verboso<\/td><\/tr><tr><td>Batch mode<\/td><td><code>mvn -B \u2026<\/code><\/td><td>CI\/CD<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">FAQs<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfQu\u00e9 es exactamente un BOM y por qu\u00e9 deber\u00eda usarlo?<\/strong><br>Un BOM es una lista de versiones coherentes para un ecosistema (p. ej., Spring). Al importarlo, heredas versiones probadas en conjunto. Ganas coherencia y reduces conflictos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfCu\u00e1ndo conviene separar Surefire y Failsafe?<\/strong><br>Siempre que tengas pruebas lentas de integraci\u00f3n. Mant\u00e9n unitarias r\u00e1pidas en <code>test<\/code> y deja integraciones para <code>verify<\/code>\/<code>integration-test<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfEs buena idea paralelizar siempre con <code>-T<\/code>?<\/strong><br>No. Mide. Algunos plugins no son thread-safe y podr\u00edas ganar poco o introducir flakiness.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfC\u00f3mo manejo credenciales de <code>deploy<\/code>?<\/strong><br>En <code>settings.xml<\/code> con variables de entorno, nunca en el POM. Usa <code>servers<\/code> y perfiles espec\u00edficos para release.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>\u00bfCu\u00e1ndo elegir\u00eda otra herramienta?<\/strong><br>Si tu build es muy din\u00e1mico y odias el XML, quiz\u00e1 prefieras otro enfoque. Pero si te importa el orden, la larga vida del proyecto y la auditablez, Maven encaja como un guante.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Sobre Maven<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Maven quiz\u00e1 no sea la herramienta \u201cde moda\u201d, pero sigue siendo el est\u00e1ndar de facto en muchos entornos empresariales por una raz\u00f3n: aporta orden, previsibilidad y un ecosistema robusto. S\u00ed, el XML puede ser verboso y, cuando te sales de la autopista, la curva se nota; pero a cambio obtienes un build estable, con convenciones claras y f\u00e1cil de mantener en equipos grandes. En mi experiencia, tratar al <code>pom.xml<\/code> como la <strong>radiograf\u00eda<\/strong> del proyecto y dominar ciclo de vida, dependencias y plugins clave es lo que separa un build fr\u00e1gil de uno confiable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Opini\u00f3n Personal<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Maven no es cool, pero es s\u00f3lido. Y en software, la solidez paga facturas. He probado alternativas m\u00e1s \u201cmodernas\u201d y, aunque me seduce su sintaxis ligera, siempre vuelvo a Maven cuando el proyecto crecer\u00e1, habr\u00e1 rotaci\u00f3n en el equipo o necesito trazabilidad quir\u00fargica. Su filosof\u00eda de orden \u2014ciclo de vida claro, convenciones estrictas y <code>pom.xml<\/code> como contrato del build\u2014 es justo lo que evita guerras de configuraci\u00f3n y \u201cmagia\u201d opaca que solo entiende quien la escribi\u00f3.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">S\u00ed, el XML es verboso. Y s\u00ed, salirse del camino feliz requiere paciencia. Pero a cambio obtienes reproducibilidad, un ecosistema de plugins maduro y una gesti\u00f3n de dependencias que te deja dormir tranquilo. Con <code>dependencyManagement<\/code> y BOMs, el caos de versiones se convierte en una conversaci\u00f3n adulta; con perfiles y <code>settings.xml<\/code>, la promoci\u00f3n de artefactos deja de ser un ritual peligroso. En CI\/CD, <code>-B<\/code>, cache del <code>~\/.m2<\/code> y paralelismo medido hacen que el build sea aburridamente predecible \u2014mi tipo favorito de aburrimiento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfEs Maven para todo? No. Si tu proyecto es experimental y cambia cada semana, quiz\u00e1 prefieras algo m\u00e1s flexible. Pero si lo que quieres es estabilidad, claridad y un est\u00e1ndar que resista el paso del tiempo, Maven sigue siendo la apuesta sensata. Para m\u00ed, no es la herramienta \u201cde moda\u201d; es la herramienta con la que termino entregando a tiempo y con menos sorpresas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora te toca: \u00bfqu\u00e9 experiencias has tenido con Maven? \u00bfTe ha salvado o te ha frustrado? D\u00e9jalo en los comentarios y lo debatimos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Qu\u00e9 es Apache Maven Maven es uno de esos veteranos que no pasan de moda. En mi d\u00eda a d\u00eda, siempre me ha dado la sensaci\u00f3n de ser ese \u201cviejo conocido\u201d del ecosistema Java: quiz\u00e1 no sea la herramienta m\u00e1s moderna del momento, pero sigue siendo la columna vertebral de much\u00edsimos proyectos serios en producci\u00f3n. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":7282,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_aifi_custom_prompt":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[192],"tags":[910,674,1092,1182,665],"class_list":["post-7281","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutoriales","tag-comandos","tag-developer","tag-java","tag-marven","tag-programacion"],"_links":{"self":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7281","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/comments?post=7281"}],"version-history":[{"count":1,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7281\/revisions"}],"predecessor-version":[{"id":7283,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/posts\/7281\/revisions\/7283"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/media\/7282"}],"wp:attachment":[{"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/media?parent=7281"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/categories?post=7281"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hostingtg.com\/blog\/wp-json\/wp\/v2\/tags?post=7281"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}