¿Puedo agregar archivos jar al classpath de compilación de Maven 2 sin instalarlos?
Maven 2 me está volviendo loco durante la fase de desarrollo de experimentación/maqueta rápida y sucia.
Tengo un pom.xml
archivo que define las dependencias del marco de la aplicación web que quiero usar y puedo generar rápidamente proyectos iniciales a partir de ese archivo. Sin embargo, a veces quiero vincularme a una biblioteca de terceros que aún no tiene un pom.xml
archivo definido, por lo que en lugar de crear el pom.xml
archivo para la biblioteca de terceros a mano e instalarlo y agregar la dependencia a mi archivo pom.xml
, simplemente me gustaría para decirle a Maven: "Además de mis dependencias definidas, incluya /lib
también los archivos jar que se encuentren".
Parece que esto debería ser sencillo, pero si lo es, me falta algo.
Cualquier sugerencia sobre cómo hacer esto será muy apreciada. Aparte de eso, si hay una manera sencilla de señalar a Maven a un /lib
directorio y crear fácilmente uno pom.xml
con todos los archivos adjuntos asignados a una única dependencia a la que luego podría nombrar/instalar y vincular de una sola vez, también sería suficiente.
Problemas de los enfoques populares.
La mayoría de las respuestas que encontrará en Internet le sugerirán que instale la dependencia en su repositorio local o especifique un alcance de "sistema" en pom
y distribuya la dependencia con la fuente de su proyecto. Pero ambas soluciones son en realidad defectuosas.
Por qué no debería aplicar el enfoque "Instalar en repositorio local"
Cuando instala una dependencia en su repositorio local, permanece allí. Su artefacto de distribución funcionará bien siempre que tenga acceso a este repositorio. El problema es que, en la mayoría de los casos, este repositorio residirá en su máquina local, por lo que no habrá forma de resolver esta dependencia en ninguna otra máquina. Claramente, hacer que su artefacto dependa de una máquina específica no es una forma de manejar las cosas. De lo contrario, esta dependencia tendrá que instalarse localmente en cada máquina que trabaje con ese proyecto, lo cual no es nada mejor.
Por qué no debería aplicar el enfoque de "alcance del sistema"
Los archivos jar de los que depende con el enfoque "Alcance del sistema" no se instalan en ningún repositorio ni se adjuntan a sus paquetes de destino. Es por eso que su paquete de distribución no tendrá una manera de resolver esa dependencia cuando se use. Creo que esa fue la razón por la que el uso del alcance del sistema incluso quedó obsoleto. De todos modos, no querrás depender de una característica obsoleta.
La solución de repositorio estático dentro del proyecto
Después de poner esto en tu pom
:
<repository>
<id>repo</id>
<releases>
<enabled>true</enabled>
<checksumPolicy>ignore</checksumPolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
<url>file://${project.basedir}/repo</url>
</repository>
para cada artefacto con una identificación de grupo del tipo x.y.z
Maven incluirá la siguiente ubicación dentro del directorio de su proyecto en su búsqueda de artefactos:
repo/
| - x/
| | - y/
| | | - z/
| | | | - ${artifactId}/
| | | | | - ${version}/
| | | | | | - ${artifactId}-${version}.jar
Para profundizar más sobre esto, puede leer esta publicación de blog .
Utilice Maven para instalar en el repositorio del proyecto
En lugar de crear esta estructura a mano, recomiendo usar un complemento de Maven para instalar sus archivos jar como artefactos. Entonces, para instalar un artefacto en un repositorio dentro del proyecto en repo
la carpeta, ejecute:
mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]
Si elige este enfoque, podrá simplificar la declaración del repositorio a pom
:
<repository>
<id>repo</id>
<url>file://${project.basedir}/repo</url>
</repository>
Un guión de ayuda
Dado que ejecutar el comando de instalación para cada biblioteca es un poco molesto y definitivamente propenso a errores, he creado un script de utilidad que instala automáticamente todos los archivos jar de una lib
carpeta en un repositorio de proyecto, mientras resuelve automáticamente todos los metadatos (groupId, artefactoId, etc.) de nombres de archivos. El script también imprime el xml de dependencias para que usted pueda copiarlo y pegarlo en su archivo pom
.
Incluya las dependencias en su paquete de destino
Cuando haya creado su repositorio en el proyecto, habrá resuelto el problema de distribuir las dependencias del proyecto con su fuente, pero desde entonces el artefacto de destino de su proyecto dependerá de archivos jar no publicados, por lo que cuando instale a un repositorio tendrá dependencias irresolubles.
Para solucionar este problema, sugiero incluir estas dependencias en su paquete de destino. Esto lo puedes hacer con el complemento Assembly o mejor con el complemento OneJar . La documentación oficial sobre OneJar es fácil de entender.
Solo para código desechable
establezca el alcance == sistema y simplemente cree un ID de grupo, un ID de artefacto y una versión.
<dependency>
<groupId>org.swinglabs</groupId>
<artifactId>swingx</artifactId>
<version>0.9.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/swingx-0.9.3.jar</systemPath>
</dependency>
Nota: las dependencias del sistema no se copian en el jar/war resultante
(consulte Cómo incluir dependencias del sistema en la guerra creada con maven ).
Puede crear un repositorio local en su proyecto.
Por ejemplo, si tiene libs
una carpeta en la estructura del proyecto
En
libs
la carpeta debes crear una estructura de directorio como:/groupId/artifactId/version/artifactId-version.jar
En tu pom.xml debes registrar el repositorio
<repository> <id>ProjectRepo</id> <name>ProjectRepo</name> <url>file://${project.basedir}/libs</url> </repository>
y agregar dependencia como de costumbre
<dependency> <groupId>groupId</groupId> <artifactId>artifactId</artifactId> <version>version</version> </dependency>
Eso es todo.
Para obtener información detallada: Cómo agregar bibliotecas externas en Maven (archivado)
Nota: Cuando se utiliza el alcance del sistema ( como se menciona en esta página ), Maven necesita rutas absolutas.
Si sus archivos jar están bajo la raíz de su proyecto, querrá anteponer los valores de ruta del sistema con ${basedir}.
Esto es lo que he hecho, también soluciona el problema del paquete y funciona con el código desprotegido.
Creé una nueva carpeta en el proyecto, en mi caso usé repo
, pero siéntete libre de usarlasrc/repo
En mi POM tenía una dependencia que no se encuentra en ningún repositorio público de Maven.
<dependency>
<groupId>com.dovetail</groupId>
<artifactId>zoslog4j</artifactId>
<version>1.0.1</version>
<scope>runtime</scope>
</dependency>
Luego creé los siguientes directorios repo/com/dovetail/zoslog4j/1.0.1
y copié el archivo JAR en esa carpeta.
Creé el siguiente archivo POM para representar el archivo descargado (este paso es opcional, pero elimina una ADVERTENCIA) y ayuda al siguiente a descubrir de dónde saqué el archivo para empezar.
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dovetail</groupId>
<artifactId>zoslog4j</artifactId>
<packaging>jar</packaging>
<version>1.0.1</version>
<name>z/OS Log4J Appenders</name>
<url>http://dovetail.com/downloads/misc/index.html</url>
<description>Apache Log4j Appender for z/OS Logstreams, files, etc.</description>
</project>
Dos archivos opcionales que creo son las sumas de verificación SHA1 para POM y el JAR para eliminar las advertencias de suma de verificación que faltan.
shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar \
> repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.jar.sha1
shasum -b < repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom \
> repo/com/dovetail/zoslog4j/1.0.1/zoslog4j-1.0.1.pom.sha1
Finalmente agrego el siguiente fragmento a mi pom.xml que me permite hacer referencia al repositorio local
<repositories>
<repository>
<id>project</id>
<url>file:///${basedir}/repo</url>
</repository>
</repositories>