Introducción
La gestión de dependencias en proyectos de Java puede ser un desafío, especialmente cuando se trabaja con artefactos que no están disponibles en repositorios públicos. En el ámbito de Maven, uno de los problemas que encontramos frecuentemente es que un artefacto puede no estar alojado en ningún lado o que el repositorio donde se encuentra sea poco confiable. En este artículo, abordaremos cómo instalar un archivo JAR localmente en un proyecto Maven utilizando el maven-install-plugin
.
La Problemática y las Opciones
1. El Problema y las Opciones
Maven es una herramienta muy versátil y sus repositorios públicos son inigualables, sin embargo, siempre habrá algún artefacto que no esté alojado en ninguna parte o cuyo repositorio sea riesgoso para depender de él, ya que puede no estar disponible cuando se necesite. Cuando esto sucede, hay varias opciones:
- Aceptar la situación e instalar una solución completa de gestión de repositorios, como Nexus.
- Intentar subir el artefacto a uno o más repositorios públicos de buena reputación.
- Instalar el artefacto localmente usando un plugin de Maven.
Nexus es, por supuesto, la solución más madura, pero también es más compleja. Configurar una instancia para que ejecute Nexus y mantenerla puede ser excesivo si solo se trata de usar un solo JAR. Sin embargo, si este escenario —la gestión de artefactos personalizados— es común, un gestor de repositorios tiene mucho sentido.
Obtener el artefacto subido a un repositorio público o al Maven Central directamente es también una buena solución, pero por lo general es un proceso largo (Guía para subir un artefacto a Maven Central). Además, es posible que la biblioteca no esté habilitada para Maven, lo que hace que el proceso sea aún más complicado. Esto no es práctico para poder usar el artefacto en este momento.
Eso nos deja con la tercera opción: agregar el artefacto en el control de versiones y usar un plugin de Maven, en este caso, maven-install-plugin para instalarlo localmente antes de que el proceso de construcción lo necesite. Esta es, con mucho, la opción más sencilla y fiable disponible.
Instalación del JAR Local con el maven-install-plugin
2. Instalación Local del JAR Con el maven-install-plugin
Comencemos con la configuración completa necesaria para instalar el artefacto en nuestro repositorio local:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<groupId>org.somegroup</groupId>
<artifactId>someartifact</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<file>${basedir}/dependencies/someartifact-1.0.jar</file>
<generatePom>true</generatePom>
</configuration>
<executions>
<execution>
<id>install-jar-lib</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
</plugin>
La información del artefacto se define como parte del elemento <configuration>
. La sintaxis es muy similar a la de declarar la dependencia: se emplean elementos <groupId>
, <artifactId>
y <version>
.
El siguiente paso de la configuración requiere definir el empaquetado del artefacto, que en este caso es especificado como jar
. Es importante también proporcionar la ubicación del archivo JAR que se desea instalar, esto puede ser una ruta de archivo absoluta o relativa, utilizando las propiedades disponibles en Maven. En este caso, la propiedad ${basedir}
representa la raíz del proyecto, que es el lugar donde existe el archivo pom.xml
. Por tanto, el archivo someartifact-1.0.jar
debe estar en un directorio /dependencies/
bajo la raíz.
Finalmente, hay otros detalles opcionales que se pueden configurar.
2.1. La Ejecución
La ejecución de la meta install-file
está unida a la fase validate
del ciclo de vida estándar de Maven (Introducción al Ciclo de Vida de Construcción). Esto significa que antes de intentar compilar, necesitarás ejecutar explícitamente la fase de validación:
mvn validate
Después de este paso, la compilación estándar funcionará:
mvn clean install
Cuando se ejecute la fase de compilación, nuestro someartifact-1.0.jar
se instalará correctamente en nuestro repositorio local, justo como cualquier otro artefacto que pueda haber sido recuperado de Maven Central.
2.2. Generando un POM vs Proporcionando el POM
La decisión de si necesitamos proporcionar un archivo pom.xml
para el artefacto depende principalmente de las dependencias en tiempo de ejecución del artefacto mismo. En términos simples, si el artefacto tiene dependencias en tiempo de ejecución de otros JARs, estos JARs tendrán que estar presentes en el classpath en tiempo de ejecución también. Con un artefacto simple, esto no debería ser un problema, ya que probablemente no tendrá dependencias en tiempo de ejecución (un “hoja” en el gráfico de dependencias).
La opción <generatePom>
en la meta install-file
debería ser suficiente para estos tipos de artefactos:
<generatePom>true</generatePom>
Sin embargo, si el artefacto es más complejo y tiene dependencias no triviales, entonces, si estas dependencias no están ya en el classpath, deben ser añadidas. Una forma de hacerlo es definiendo estas nuevas dependencias manualmente en el archivo POM del proyecto. Una mejor solución es proporcionar un archivo pom.xml
personalizado junto con el artefacto instalado:
<generatePom>false</generatePom>
<pomFile>${basedir}/dependencies/someartifact-1.0.pom</pomFile>
Esto permitirá que Maven resuelva todas las dependencias del artefacto definidas en este archivo pom.xml
personalizado, sin necesidad de definirlas manualmente en el archivo POM principal del proyecto.
Usando Comandos Maven
3. Usando Comandos de Maven
En esta sección, aprenderemos cómo usar comandos de Maven para instalar un JAR local. Discutiremos la instalación y el uso del JAR en un proyecto simple.
3.1. Configuración del JAR
Primero, veamos la estructura de archivos de nuestro proyecto de biblioteca utilizando el comando exa
:
$ exa --tree .
.
├── com
│ └── baeldung
│ └── HelloWorld.java
└── manifest.txt
Aquí, el proyecto de biblioteca contiene un único archivo HelloWorld.java
y un archivo manifest.txt
.
Veamos ahora el método hello()
en la clase HelloWorld
:
package com.baeldung;
public class HelloWorld {
public static void hello() {
System.out.println("Hello, world!");
}
public static void main() {
hello();
}
}
A continuación, compilamos el archivo HelloWorld.java
para generar la clase HelloWorld
y actualizamos el archivo manifest.txt
:
$ javac com/baeldung/HelloWorld.java
$ cat manifest.txt
Main-Class: com.baeldung.HelloWorld
Por último, empaquetamos nuestro archivo de biblioteca en el archivo HelloWorld.jar
:
$ jar cvfm HelloWorld.jar manifest.txt com/baeldung/HelloWorld.class
added manifest
adding: com/baeldung/HelloWorld.class(in = 479) (out= 320)(deflated 33%)
3.2. Instalar HelloWorld.jar
Ahora que tenemos el archivo JAR, utilizaremos el comando mvn install:install-file
para instalarlo en el repositorio local:
$ mvn install:install-file \
-Dfile=HelloWorld.jar \
-DgroupId=com.baeldung \
-DartifactId=hello-world \
-Dversion=1.0 \
-Dpackaging=jar
Es importante notar que no teníamos un pom.xml
para nuestro proyecto de biblioteca, por lo que hemos proporcionado la información de groupId
, artifactId
, version
, y packaging
usando la opción -D
.
Además, verifiquemos que el archivo JAR se haya instalado en el repositorio local .m2
utilizando el comando exa
:
$ exa --tree ~/.m2/repository/com/baeldung/hello-world
/Users/tavasthi/.m2/repository/com/baeldung/hello-world
├── 1.0
│ ├── _remote.repositories
│ ├── hello-world-1.0.jar
│ └── hello-world-1.0.pom
└── maven-metadata-local.xml
¡Excelente! Hemos obtenido con éxito el archivo. Además, podemos ver que el comando generó un archivo pom.xml
.
3.3. Usar HelloWorld.jar en un Proyecto
Para utilizar el proyecto, crearemos el proyecto Maven my-project
utilizando el comando mvn
:
$ mvn archetype:generate \
-DgroupId=com.baeldung \
-DartifactId=my-project \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
Ahora, veamos la estructura del directorio de nuestro proyecto utilizando el comando exa
:
$ exa --tree my-project
my-project
├── pom.xml
└── src
├── main
│ └── java
│ └── com
│ └── baeldung
│ └── App.java
└── test
└── java
└── com
└── baeldung
└── AppTest.java
A continuación, agregaremos la dependencia hello-world
en el archivo pom.xml
del proyecto:
<dependency>
<groupId>com.baeldung</groupId>
<artifactId>hello-world</artifactId>
<version>1.0</version>
</dependency>
Ahora, llamemos al método hello()
de nuestra biblioteca en nuestro proyecto de destino:
public class App {
public static void main( String[] args ) {
com.baeldung.HelloWorld.hello();
}
}
Finalmente, veamos esto en acción ejecutando nuestro proyecto de destino:
$ mvn clean install && mvn exec:java -Dexec.mainClass="com.baeldung.App"
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.baeldung:my-project >-----------------------
[INFO] Building my-project 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- exec:3.1.0:java (default-cli) @ my-project ---
Hello, world!
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.232 s
[INFO] Finished at: 2023-06-14T17:42:31+05:30
[INFO] ------------------------------------------------------------------------
¡Fantástico! Podemos ver que el método hello()
se ejecutó con éxito.
Conclusión
En este artículo, hemos revisado cómo usar un JAR que no está alojado en ningún lugar dentro de un proyecto Maven instalándolo localmente con el maven-install-plugin
. Además, hemos usado comandos de Maven para configurar e instalar un JAR local, seguido de su uso en un proyecto de destino.
Asegúrate de seguir estas prácticas al trabajar con artefactos en tus proyectos de Java. Tener un manejo efectivo de tus dependencias asegurará que tus proyectos se construyan y funcionen correctamente, minimizando problemas en el futuro.