¿Puedo agregar jar a maven 2 classpath build sin instalarlos?

Maven2 me está volviendo loco durante la fase de experimentación / maqueta rápida y sucia del desarrollo.

Tengo un archivo pom.xml que define las dependencias para el 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 deseo vincular una biblioteca de terceros que aún no tiene un archivo pom.xml definido, así que en lugar de crear el archivo pom.xml para la lib de terceros a mano, instalarlo y agregar la dependencia a my pom.xml , me gustaría decirle a Maven: “Además de mis dependencias definidas, incluye los archivos jar que están en /lib también”.

Parece que esto debería ser simple, pero si lo es, me falta algo.

Cualquier sugerencia sobre cómo hacer esto es muy apreciada. En resumen, si hay una manera simple de apuntar maven a un directorio /lib y crear fácilmente un pom.xml con todos los jars adjuntos mapeados a una única dependencia que podría nombrar / instalar y enlazar de una sola vez también es suficiente.

Problemas de enfoques populares

La mayoría de las respuestas que encontrará en Internet le sugerirán instalar la dependencia en su repository local o especificar un scope de “sistema” en el pom y distribuir la dependencia con el origen de su proyecto. Pero ambas soluciones son defectuosas.

Por qué no debes aplicar el enfoque “Instalar a Repo Local”

Cuando instala una dependencia en su repository local, permanece allí. Su artefacto de distribución funcionará bien siempre que tenga acceso a este repository. El problema es que en la mayoría de los casos este repository 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, que no es mejor.

Por qué no debes aplicar el enfoque de “Alcance del sistema”

Los flasks de los que depende con el enfoque “Alcance del sistema” no se instalan en ningún repository 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. Esa es la razón por la cual el uso del scope del sistema incluso se desaprovechó. De todos modos, no quiere confiar en una característica en desuso.

La solución de repository estática en el proyecto

Después de poner esto en tu pom :

  repo  true ignore   false  file://${project.basedir}/repo  

para cada artefacto con un ID de grupo de la forma xyz Maven incluirá la siguiente ubicación dentro de su directorio de proyecto en su búsqueda de artefactos:

 repo/ | - x/ | | - y/ | | | - z/ | | | | - ${artifactId}/ | | | | | - ${version}/ | | | | | | - ${artifactId}-${version}.jar 

Para obtener más información sobre esto, puede leer esta publicación en el blog .

Utilice Maven para instalar el repository del proyecto

En lugar de crear esta estructura a mano, recomiendo utilizar un plugin Maven para instalar sus jarras como artefactos. Por lo tanto, para instalar un artefacto en un repository dentro del proyecto en la carpeta repo ejecutar:

 mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...] 

Si elige este enfoque, podrá simplificar la statement del repository en pom para:

  repo file://${project.basedir}/repo  

Una secuencia de comandos de ayuda

Dado que ejecutar el comando de instalación para cada lib es algo molesto y definitivamente propenso a errores, he creado un script de utilidad que instala automáticamente todos los jar desde una carpeta lib a un repository de proyecto, mientras se resuelven automáticamente todos los metadatos (groupId, artifactId y etc.) de los nombres de los archivos. El script también imprime las dependencias xml para que copie y pegue en su pom .

Incluye las dependencias en tu paquete objective

Cuando haya creado su repository en proyecto, habrá resuelto un problema de distribución de las dependencias del proyecto con su origen, pero desde entonces el artefacto objective de su proyecto dependerá de jarras no publicadas, de modo que cuando lo instale a un repository, tendrá dependencias irresolubles.

Para vencer este problema, sugiero que incluya estas dependencias en su paquete de destino. Esto se puede hacer con el Complemento de ensamblaje o mejor con el Complemento de OneJar . La documentación oficial de OneJar es fácil de entender.

Solo para el código de descarte

establecer el scope == sistema y simplemente crear un groupId, artifactId y versión

  org.swinglabs swingx 0.9.2 system ${project.basedir}/lib/swingx-0.9.3.jar  

Nota: las dependencias del sistema no se copian en jar / guerra resultante
(ver Cómo incluir dependencias del sistema en war build usando maven )

Puede crear un repository local en su proyecto

Por ejemplo, si tiene una carpeta libs en la estructura del proyecto

  • En la carpeta libs debe crear una estructura de directorios como: /groupId/artifactId/version/artifactId-version.jar

  • En tu pom.xml debes registrar el repository

      ProjectRepo ProjectRepo file://${project.basedir}/libs  
  • y agrega dependencia como de costumbre

      groupId artifactId version  

Eso es todo.

Para información detallada: Cómo agregar bibliotecas externas en Maven

Nota: Al usar el scope del sistema ( como se menciona en esta página ), Maven necesita rutas absolutas.

Si sus archivos jar están debajo de la raíz de su proyecto, querrá prefijar los valores de SystemPath con $ {basedir}.

Realmente debería tener un marco en su lugar a través de un repository e identificar sus dependencias por adelantado. Usar el scope del sistema es un error común que las personas usan, porque “no les importa la gestión de la dependencia”. El problema es que al hacer esto terminas con una construcción maven pervertida que no muestra al maven en condiciones normales. Sería mejor seguir un enfoque como este .

Esto es lo que he hecho, también funciona con el problema del paquete y funciona con el código desprotegido.

Creé una nueva carpeta en el proyecto, en mi caso utilicé repo , pero puede usar src/repo

En mi POM tuve una dependencia que no está en ningún repository maven público

  com.dovetail zoslog4j 1.0.1 runtime  

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 chico a averiguar dónde obtuve el archivo para comenzar.

 < ?xml version="1.0" encoding="UTF-8" ?>  4.0.0 com.dovetail zoslog4j jar 1.0.1 z/OS Log4J Appenders http://dovetail.com/downloads/misc/index.html Apache Log4j Appender for z/OS Logstreams, files, etc.  

Dos archivos opcionales que creo son las sums de comprobación SHA1 para el POM y el JAR para eliminar las advertencias de sum de comprobación faltantes.

 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 referirme al repository local

   project file:///${basedir}/repo   

El plugin de instalación de Maven tiene un uso de línea de comando para instalar un jar en el repository local, POM es opcional pero tendrás que especificar GroupId, ArtifactId, Version y Packaging (todo el material de POM).

Así es como agregamos o instalamos un contenedor local

   org.example iamajar 1.0 system ${project.basedir}/lib/iamajar.jar  

di algunos groupId y artifactId predeterminados porque son obligatorios 🙂

Usar el system es una idea terrible por razones explicadas por otros, instalar el archivo manualmente en el repository local hace que la comstackción no sea reproducible, y usar file://${project.basedir}/repo no es una buena idea porque (1) puede no ser una URL de file bien formada (por ejemplo, si el proyecto está desprotegido en un directorio con caracteres inusuales), (2) el resultado no se puede utilizar si el POM de este proyecto se usa como una dependencia del proyecto de otra persona.

Suponiendo que no está dispuesto a subir el artefacto a un repository público, la sugerencia de Simeon de un módulo auxiliar hace el trabajo. Pero ahora hay una manera más fácil …

La recomendación

Use el plugin no maven-jar-maven . Hace exactamente lo que estaba pidiendo, sin ninguno de los inconvenientes de los otros enfoques.

Encontré otra manera de hacer esto, mira aquí desde una publicación de Heroku

Para resumir (lo siento por algunos copiar y pegar)

  • Crea un directorio repo debajo de tu carpeta raíz:
 tu proyecto
 + - pom.xml
 + - src
 + - repo
  • Ejecute esto para instalar el archivo jar en su directorio de repository local
 mvn deploy: deploy-file -Durl = file: /// path / to / yourproject / repo / -Dfile = mylib-1.0.jar -DgroupId = com.example -DadifactId = mylib -Dpackaging = jar -Dversion = 1.0
  • Añada esto su pom.xml :
    project.local project file:${project.basedir}/repo    com.example mylib 1.0  

Después de una larga discusión con los chicos de CloudBees acerca del empaque adecuado de este tipo de JAR, hicieron una buena propuesta interesante para una solución:

Creación de un proyecto Maven falso que conecta un JAR preexistente como artefacto principal, ejecutándose en la instalación de POM perteneciente: ejecución de instalación de archivo. Aquí hay un ejemplo de tal kinf de POM:

     org.apache.maven.plugins maven-install-plugin 2.3.1   image-util-id install  install-file   ${basedir}/file-you-want-to-include.jar ${project.groupId} ${project.artifactId} ${project.version} jar       

Pero para implementarlo, la estructura del proyecto existente debería cambiarse. En primer lugar, debe tener en cuenta que para cada tipo de JAR debería crearse un proyecto falso diferente (módulo). Y debería crearse un proyecto padre Maven que incluya todos los submódulos que son: todos los contenedores JAR y el proyecto principal existente. La estructura podría ser:

proyecto raíz (este contiene el archivo POM principal incluye todos los submódulos con el elemento XML del módulo ) (empaque POM)

Recubrimiento JAR 1 Proyecto infantil Maven (embalaje POM)

Recubrimiento JAR 2 Proyecto infantil Maven (embalaje POM)

principal proyecto Maven hijo existente (WAR, JAR, EAR … packaging)

Cuando se ejecuta el padre ejecutando a través de mvn: install o mvn: packaging y se ejecutan los submódulos. Eso podría ser un inconveniente aquí, ya que la estructura del proyecto debería cambiarse, pero ofrece una solución no estática al final

El problema con systemPath es que las jarras de las dependencias no se distribuirán a lo largo de tus artefactos como dependencias transitivas. Pruebe lo que he publicado aquí: ¿es mejor materaizar los archivos jar de su proyecto o ponerlos en WEB-INF / lib?

Luego declara las dependencias como de costumbre.

Y por favor lea la nota del pie de página.

Si quieres una solución rápida y sucia, puedes hacer lo siguiente (aunque no lo recomiendo para nada excepto para proyectos de prueba, maven se quejará de que esto no es correcto).

Agregue una entrada de dependencia para cada archivo jar que necesite, preferiblemente con un script perl o algo similar y cópielo / péguelo en su archivo pom.

 #! /usr/bin/perl foreach my $n (@ARGV) { $n=~s@.*/@@; print " local.dummy $n 0.0.1 system \${project.basedir}/lib/$n  "; 

Una solución de lote rápida y sucia (basada en la respuesta de Alex):

libs.bat

 @ECHO OFF FOR %%I IN (*.jar) DO ( echo ^ echo ^local.dummy^ echo ^%%I^ echo ^0.0.1^ echo ^system^ echo ^${project.basedir}/lib/%%I^ echo ^ ) 

libs.bat > libs.txt : libs.bat > libs.txt . A continuación, abra libs.txt y copie su contenido como dependencias.

En mi caso, solo necesitaba las bibliotecas para comstackr mi código, y esta solución fue la mejor para ese propósito.

Una extraña solución que encontré:

usando Eclipse

  • crear un proyecto java simple (no maven)
  • agregar una clase principal
  • agregar todos los jar a classpath
  • exportar JAR ejecutable (es importante, porque no hay otra manera aquí para hacerlo)
  • seleccione Extraer las bibliotecas necesarias en el JAR generado
  • decidir los problemas de licencia
  • tadammm … instala el jar generado en tu m2repo
  • agrega esta única dependencia a tus otros proyectos.

salud, Balint

Aunque no se ajusta exactamente a su problema, dejaré esto aquí. Mis requisitos fueron:

  1. Los tarros que no se pueden encontrar en un repository de maven en línea deben estar en el SVN.
  2. Si un desarrollador agrega otra biblioteca, los otros desarrolladores no deberían molestarse en instalarlos manualmente.
  3. El IDE (NetBeans en mi caso) debería poder encontrar las fonts y javadocs para proporcionar autocompletado y ayuda.

Primero hablemos de (3): no bastará con tener los flasks en una carpeta y fusionarlos de algún modo en el flask final, ya que el IDE no lo comprenderá. Esto significa que todas las bibliotecas deben instalarse correctamente. Sin embargo, no quiero que todos lo instalen usando “mvn install-file”.

En mi proyecto necesitaba metawidget. Aquí vamos:

  1. Crea un nuevo proyecto maven (llámalo “shared-libs” o algo así).
  2. Descarga metawidget y extrae el zip en src / main / lib.
  3. La carpeta doc / api contiene los javadocs. Crea un archivo zip del contenido (doc / api / api.zip).
  4. Modificar el pom como este
  5. Construya el proyecto y la biblioteca será instalada.
  6. Agregue la biblioteca como una dependencia a su proyecto, o (si agregó la dependencia en el proyecto shared-libs) agregue shared-libs como dependencia para obtener todas las bibliotecas a la vez.

Cada vez que tenga una nueva biblioteca, simplemente agregue una nueva ejecución y dígales a todos que vuelvan a construir el proyecto (puede mejorar este proceso con las jerarquías del proyecto).

Lo que me parece más simple es configurar tu plugin maven-compiler para incluir tus jar personalizados. Este ejemplo cargará cualquier archivo jar en un directorio lib.

   org.apache.maven.plugins maven-compiler-plugin   lib/*.jar    

Para instalar el jar de terceros que no está en el repository de maven, use maven-install-plugin.

A continuación se muestran los pasos:

  1. Descargue el archivo jar manualmente de la fuente (sitio web)
  2. Crea una carpeta y coloca tu archivo jar en ella
  3. Ejecute el siguiente comando para instalar el jar de terceros en su repository local de maven

mvn install: install-file -Dfile = -DgroupId = -DadifactId = -Dversion = -Dpackaging =

A continuación está el ejemplo, yo lo usé para simonsite log4j

mvn install: install-file -Dfile = / Users / athanka / git / MyProject / repo / log4j-rolling-appender.jar -DgroupId = uk.org.simonsite -DadifactId = log4j-rolling-appender -Dversion = 20150607-2059 – Dpackaging = jar

  1. En el pom.xml incluye la dependencia como abajo

       uk.org.simonsite log4j-rolling-appender 20150607-2059  
  2. Ejecute el comando mvn clean install para crear su empaque

Debajo está el enlace de referencia:

https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html

Para aquellos que no encontraron una buena respuesta aquí, esto es lo que estamos haciendo para obtener un contenedor con todas las dependencias necesarias. Esta respuesta ( https://stackoverflow.com/a/7623805/1084306 ) menciona el uso del complemento Maven Assembly, pero en realidad no da un ejemplo en la respuesta. Y si no lee todo el camino hasta el final de la respuesta (es bastante largo), puede perderse. Si agrega lo siguiente a su pom.xml, se generará target/${PROJECT_NAME}-${VERSION}-jar-with-dependencies.jar

   org.apache.maven.plugins maven-assembly-plugin 2.4.1    jar-with-dependencies     my.package.mainclass      make-assembly  package  single     

Esto no responde cómo agregarlos a su POM, y puede ser una obviedad, ¿pero simplemente agregaría el directorio lib a su trabajo classpath? Sé que eso es lo que hago cuando necesito un contenedor externo que no quiero agregar a mis repositorys Maven.

Espero que esto ayude.

Lo que funciona en nuestro proyecto es lo que Archimedes Trajano escribió, pero teníamos en nuestro archivo .m2 / settings.xml algo como esto:

   nexus * http://url_to_our_repository  

y el * debe cambiarse a central. Entonces, si su respuesta no funciona para usted, debe verificar su configuración.xml

Aludí a un código python en un comentario a la respuesta de @alex Lehmann, así que lo publico aquí.

 def AddJars(jarList): s1 = '' for elem in jarList: s1+= """  local.dummy %s 0.0.1 system ${project.basedir}/manual_jars/%s \n"""%(elem, elem) return s1 

Solo quería una solución rápida y sucia … No podía ejecutar el script de Nikita Volkov: error de syntax + requiere un formato estricto para los nombres de los jar.

Hice este script Perl que funciona con cualquier formato para los nombres de los archivos jar, y genera las dependencias en un xml para que pueda copiarse pegado directamente en un pom.

Si desea usarlo, asegúrese de comprender lo que está haciendo el script, puede necesitar cambiar la carpeta lib y el valor para groupId o artifactId

 #!/usr/bin/perl use strict; use warnings; open(my $fh, '>', 'dependencies.xml') or die "Could not open file 'dependencies.xml' $!"; foreach my $file (glob("lib/*.jar")) { print "$file\n"; my $groupId = "my.mess"; my $artifactId = ""; my $version = "0.1-SNAPSHOT"; if ($file =~ /\/([^\/]*?)(-([0-9v\._]*))?\.jar$/) { $artifactId = $1; if (defined($3)) { $version = $3; } `mvn install:install-file -Dfile=$file -DgroupId=$groupId -DartifactId=$artifactId -Dversion=$version -Dpackaging=jar`; print $fh "\n\t$groupId\n\t$artifactId\n\t$version\n\n"; print " => $groupId:$artifactId:$version\n"; } else { print "##### BEUH...\n"; } } close $fh;