Dependencias con maven

De ChuWiki
Saltar a: navegación, buscar

Viene de Tutorial de Maven

Uno de los puntos fuertes de maven son las dependencias. En nuestro proyecto podemos decirle a maven que necesitamos un jar (por ejemplo, log4j o el conector de MySQL) y maven es capaz de ir a internet, buscar esos jar y bajárselos automáticamente. Es más, si alguno de esos jar necesitara otros jar para funcionar, maven "tira del hilo" y va bajándose todos los jar que sean necesarios. Vamos a ver todo esto con un poco de detalle.

Repositorios maven

En internet hay repositorios de jars preparados para que los entienda maven y ahí es donde maven va a buscar los jar cuando los necesita. El repositorio oficial de maven es http://repo1.maven.org/maven2/ Si navegamos por esa URL iremos encontrando un montón de jar de un montón de librerías de libre distribución. Por ejemplo, si nuestro proyecto necesita log4j y el conector de MySQL, maven encontrará las distintas versiones de estos jar en http://repo1.maven.org/maven2/log4j/log4j/ y http://repo1.maven.org/maven2/mysql/mysql-connector-java/

Añadir dependencias en nuestro proyecto

Para indicarle a maven que necesitamos un jar determinado, debemos editar el fichero pom.xml que tenemos en el directorio raíz de nuestro proyecto. En el pom.xml generado por defecto por maven veremos un trozo como el siguiente:

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

Esta es una dependencia que pone maven automáticamente cuando creamos nuestro proyecto. Presupone que vamos a usar junit y en concreto, la versión 3.8.1. Si nosotros queremos añadir más dependencias, debemos poner más trozos como este. Por ejemplo, si añadimos las dependencias de log4j 1.2.13 y del conector de mysql versión 5.1.12, debemos poner lo siguiente

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.13</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.12</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>

Veamos qué significa cada una de las etiquetas que hemos puesto. Como comentamos en el artículo anterior, maven identifica los jar por tres parámetros: groupId, artifactId y número de versión.

  • El groupId identifica normalmente a un proyecto o una empresa. Yo por ejemplo, suelo poner como groupId en todos mis proyectos com.chuidiang. MySQL ha decidido poner mysql y log4j pues log4j.
  • El artifactId es el nombre concreto del jar.
  • version es el número de versión que queremos.

El <scope> es para qué necesitamos el jar. Hay varias opciones, pero las más habituales son test, compile y runtime.

  • test, quiere decir que ese jar sólo se necesita para ejecutar los test o programas de prueba. El ejemplo evidente es el propio jar de junit.
  • compile quiere decir que es necesario para que nuestro jar compile. Es el caso de log4j si vamos a andar instanciando y usando loggers por nuestro código.
  • runtime es que sólo se necesita en tiempo de ejecución, pero no para compilar. Habitualmente es el caso de los drivers de conexión con base de datos, ya que al referenciarlos con un Class.forName("com.mysql.jdbc.Driver") no es necesario depender de ellos en compilación, pero sí en ejecución.

Una vez hecho esto, si compilamos nuestro proyecto con mvn compile o mvn package, veremos como maven se descarga de internet estos jars, siempre y cuando no los tengamos ya (sólo veremos la descarga la primera vez que ejecutemos el comando).

Buscadores de jars

Hasta ahora muy bonito, pero la pregunta evidente es ¿cómo sé cual es el groupId y artifactId de un determinado jar para ponerlo en el fichero pom.xml?.

La respuesta más oficial/elegante es que hay buscadores de jars para maven, como http://mvnrepository.com/ Poniendo en la caja de búsqueda el nombre de la librería (por ejemplo, mysql) nos irá mostrando opciones y navegando por ellas, pulsando al final en "details", tendremos el <dependency> completo que tenemos que poner en maven. En este enlace puedes ver el resultado para nuestro conector de mysql http://mvnrepository.com/artifact/mysql/mysql-connector-java/5.1.12

También suele ser normal copiar la <dependency> de otro proyecto anterior donde ya la tengamos puesta o mirar buscar en el mismo repositorio el jar y junto a él suele haber un fichero pom.xml propio del proyecto. En ese pom.xml podemos ver el groupId, artifactId y versión que tiene el proyecto. Incluso se puede deducir de la URL, ya que por debajo del subdirectorio maven2 suele ir el groupId, el último path suele ser el artifactId y la versión.

Repositorio local

¿Dónde deja maven los jar que se baja?. Por defecto, en el <codeHOME</code> del usuario, crea un subdirectorio .m2/repository y ahí va dejando todos los jar que se va bajando de internet. Es más, los deja con una estructura similar a la del respositorio, creando subdirectorios por groupId, por artifactId y por version. Cuando compilamos con mvn compile o </code>mvn package</code>, maven mira primero si los jar que necesitan ya están en el respositorio local en $HOME/.m2/repository. Si ya están los usa sin más. Si no están, los busca en internet, los pone en nuestro $HOME/.m2/repository y los usa.

Comentamos en el artículo anterior que maven hace un tratamiento algo distinto de los jar cuya versión termina en SNAPSHOT. Podemos aquí empezar a ver esa diferencia. Como comentamos, maven considera que un jar cuya versión termine en SNAPSHOT (por ejemplo, proyecto1-1.0-SNAPSHOT) es una versión que está todavía en desarrollo y que por tanto, va a tener frecuentes modificaciones.

Pues bien, si dependemos de un jar en versión SNAPSHOT, maven mirará de qué fecha es el jar que tenemos en nuestro repositorio $HOME/.m2/repository y aunque ya lo tengamos, si es anterior al día de hoy, ira de todas formas a internet a ver si hay una versión más moderna. Si la hay, se la bajará y será la que utilice. Esto no sucede con las versiones normales no SNAPSHOT (por ejemplo, log4j-1.2.13.jar). Maven considera que esa versión es estable y no se va a modificar más, por lo que si la tenemos en nuestro $HOME/.m2/repository, no irá a internet a ver si hay una más moderna.

Finalmente, si dentro de nuestro ordenador tenemos varios proyectos maven y queremos usar los jar que hemos generado en uno de ellos en otro de los proyectos, podemos subir esos jar al repositorio local. El comando es mvn install. Este comando compila, pasa los test de JUnit, genera el jar y lo sube a nuestro $HOME/.m2/repository con el groupId, artifactId y versión que hayamos decidido cuando creamos el proyecto. En el momento que este jar está en nuestro $HOME/.m2/repository, ya está accesible para cualquier otro proyecto maven en el mismo ordenador.