Les artefacts nécessaires à maven sont téléchargés juste-à-temps, soit depuis un référentiel distant, soit depuis un référentiel local (par défaut: ~/.m2/repository) qui agit comme un cache. Ceci concerne les plugins, les dépendances des projets, les POM...  

Référentiels distants

Il existe de très  nombreux référentiels différents.

Le référentiel central

Contrôlé par l'équipe maven, il contient tous les artefacts Java qu'il est possible de redistribuer (en fonction des différentes licences. Son adresse principale est http://www.ibiblio.org/maven2 et il est répliqué aux adresses suivantes :

Ces serveurs étant généralement surchargés, il existe des maven-proxy permettant de centraliser pour une équipe les accès au référentiel.

Référentiels particuliers

Certains fournisseurs de logiciels choisissent de distribuer leurs artefacts eux-mêmes. Il est possible - et même conseillé ! de mettre en place un référentiel pour toute l'entreprise contenant :  

Accés aux référentiels

maven utilise Wagon pour transporter tous ses artefacts. En théorie, cet utilitaire permet d'utiliser une grande variété de protocoles : HTTP, HTTPS, FTP, SFTP, SCP, WebDAV... En pratique, la situation est plus compliqué, les version officielles gérant mal autre chose que le HTTP et SCP.  

Le fragment de POM suivant permet de contourner un bug dans wagon pour l'utilisation d'un programme ssh externe :

  <extensions>
   <extension>
    <groupId>org.apache.maven.wagon</groupId>
    <artifactId>wagon-ssh-external</artifactId>
    <version>1.0-alpha-5</version>
   </extension>
  </extensions>

Pour le HTTPS avec authentification par certificat, c'est-à-dire lorsque le client utilise un certificat signé pour s'authentifier auprès du serveur, il est nécessaire de paramétrer l'environnement d'exécution de Java pour configurer SSL

Le référentiel commun (à l'entreprise ou au projet) sert aussi à déployer les artefacts produits par le projet. Il est préférable de séparer les référentiels :

La figure suivante résume les interactions entre ces différents référentiels.

null

En pratique, en mode projet, on se trouve souvent dans la situation suivante :

null

Utilisation des référentiels

La configuration d'utilisation des référentiels est généralement fonction du projet, tous les dévelopeurs partageant la même configuration au travers du POM. L'authentification dépendant de l'utilisateur courant, ses paramétres iront dans le fichier ~/.m2/settings.xml, dans la balise <servers />.  

Mise en place de plusieurs référentiels

http://maven.apache.org/guides/mini/guide-multiple-repositories.html

Le POM peut contenir la définition des différents référentiels à utiliser, chaque référentiel étant identifié de manière unique dans un certain projet.

<project>
...
  <repositories>
    <repository>
      <id>my-repo1</id>
      <name>your custom repo</name>
      <url>http://jarsm2.dyndns.dk</url>
    </repository>
    <repository>
      <id>my-repo2</id>
      <name>your custom repo</name>
      <url>http://jarsm2.dyndns.dk</url>
    </repository>
  </repositories>
...
</project>

Les référentiels sont hérités par l'ensemble des POM fils il est donc nécessaire de les préciser uniquement dans le projet racine. Par défaut, un certain nombre de référentiels standards sont hérités :

Le fichier ~/.m2/settings.xml peut aussi contenir des définitions de référentiels en fonction de profils, un profil étant activé par l'utilisation de la balise <activeProfile> ou du paramètre -PprofilId dans la ligne de commande maven

<settings>
 ...
 <profiles>
   ...
   <profile>
     <id>myprofile</id>
     <repositories>
       <repository>
         <id>my-repo2</id>
         <name>your custom repo</name>
         <url>http://jarsm2.dyndns.dk</url>
       </repository>
     </repositories>
   </profile>
   ...
 </profiles>


 <activeProfiles>
   <activeProfile>myprofile</activeProfile>
 </activeProfiles>
 ...
</settings>

En redéfinissant l'URL de central pour les artefacts et les plugins, on a la possibilité de mettre en place des caches ou des proxies ce qui est aussi possible par définition d'une balise <proxy> dans le fichier  de paramétrage.

La balise <server> permet d'associer des éléments d'authentification avec un serveur et donc un référentiel.

Utilisation de miroirs

Le paramétrage local (~/.m2/settings.xml) permet de définir des mirroirs pour tout ou partie des référentiels utilisés par un projet.  

<settings>
  .
  .
  <mirrors>
    <mirror>
      <id>planetmirror.com</id>
      <name>planetmirror Mirror of http://repo1.maven.org/maven2/</name>
      <url>http://public.planetmirror.com/pub/maven2</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
  .
  .
</settings>

Une balise <mirror> définit une adresse alternative pour un certain référentiel en fonction de son identifiant : lorsqu'un artefact doit être téléchargé depuis le référentiel en question (ce qui est normalement fonction des dépendances éventuellement transitives du POM et des paramètres du projet), le miroir sera d'abord utilisé avant le référentiel répliqué.  

Utilisation de proxy

Le paramétrage local (~/.m2/settings.xml) permet de définir des proxies pour tout ou partie des serveurs référentiels utilisés par un projet.  

<settings>
  .
  .
  <proxies>
   <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>proxy.somewhere.com</host>
      <port>8080</port>
      <username>proxyuser</username>
      <password>somepassword</password>
      <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
    </proxy>
  </proxies>
  .
  .
</settings>


A la différence d'un miroir, un proxy est utilisé en fonction de l'adresse d'un serveur et non de l'identifiant d'un référentiel : les deux mécanismes sont complémentaires et permettent de pallier aux déficiences locales tout en maîtrisant l'origine des dépendances dans le POM.

Structure des référentiels

L'arborescence d'un référentiel est basé sur l'ensemble des élements définissant de manière unique un artefact :

Ces éléments sont concaténés pour définir une URI dans le référentiel :

groupId/artifactId/version/artifactId-version.jar
groupId/artifactId/version/artifactId-version.pom
...

Problèmes

L'ancienne structure de référentiel utilisée dans maven1 est toujours présente et les noms de groupe ne sont pas toujours consistants : les artefacts du projet jakarta-commons par exemple se trouvent chacun dans leur groupe au lieu d'être référencés dans le groupe org.apache.commons par exemple.

Pour des raisons de licence, certains artefacts ne sont pas distribués directement dans le référentiel central mais indirectement par  indication d'une URL de téléchargement. Par exemple, pour javax.mail :  

[...]
  <distributionManagement>
    <downloadUrl>http://java.sun.com/products/javamail/downloads/index.html</downloadUrl>
  </distributionManagement>
[...]

Il est intéressant dans un contexte d'entreprise de mettre en place un référentiel dédié aux artefacts manquants qui sera peuplé de ce type d'éléments avec le POM et les fichiers de checksum

Politique de gestion

Un référentiel peut être configuré pour la gestion:

Dans le référentiel local, pour chaque artefact, maven stocke des informations relatives aux référentiels distants dans des fichiers maven-metadata-xxx.xmlxxx correspond à un identifiant de référentiel dans un POM ou le fichier de configuration. Ce fichier contient des informations sur les versions disponibles dans le référentiel xxx ainsi que la date à laquelle il a été interrogé pour la derniére fois:

Exemple

L'artefact speculoos-rt en version 1.0-SNAPSHOT. Le fichier maven-metadata-sf.net.xml contient:

<?xml version="1.0" encoding="UTF-8"?><metadata>
  <groupId>speculoos</groupId>
  <artifactId>speculoos-rt</artifactId>
  <version>1.0-SNAPSHOT</version>
  <versioning>
    <snapshot>
      <timestamp>20060621.205335</timestamp>
      <buildNumber>3</buildNumber>
    </snapshot>
    <lastUpdated>20060621205648</lastUpdated>
  </versioning>
</metadata>

Le répertoire du référentiel local contient:

    307 2006-06-21 22:55 maven-metadata-local.xml
    353 2006-06-21 22:58 maven-metadata-sf.net.xml
     40 2006-06-21 22:58 maven-metadata-sf.net.xml.sha1
    165 2006-06-20 18:05 maven-metadata-srvue.norsys.fr.xml
127968 2006-06-20 13:16 speculoos-rt-1.0-20060620.111503-1.jar
   1092 2006-06-20 13:17 speculoos-rt-1.0-20060620.111503-1.pom
 215786 2006-06-20 13:17 speculoos-rt-1.0-20060620.111503-1-tests.jar
 131961 2006-06-21 22:51 speculoos-rt-1.0-20060621.204848-2.jar
   1092 2006-06-21 22:52 speculoos-rt-1.0-20060621.204848-2.pom
 219503 2006-06-21 22:52 speculoos-rt-1.0-20060621.204848-2-tests.jar
 131960 2006-06-21 22:56 speculoos-rt-1.0-20060621.205335-3.jar
   1092 2006-06-21 22:57 speculoos-rt-1.0-20060621.205335-3.pom
 219502 2006-06-21 22:58 speculoos-rt-1.0-20060621.205335-3-tests.jar
 131960 2006-06-21 22:55 speculoos-rt-1.0-SNAPSHOT.jar
   1083 2006-06-21 22:55 speculoos-rt-1.0-SNAPSHOT.pom
 219502 2006-06-21 22:55 speculoos-rt-1.0-SNAPSHOT-tests.jar

La version enregistrée dans le fichier metadata est bien la dernière version.

A contrario, le fichier maven-metadata-srvue.norsys.fr.xml contient:

<?xml version="1.0" encoding="UTF-8"?><metadata>
  <groupId>speculoos</groupId>
  <artifactId>speculoos-rt</artifactId>
  <version>1.0-SNAPSHOT</version>
</metadata>
ce qui indique qu'aucune version de cet artefact n'est disponible (pour l'instant) sur ce serveur.

Référentiel de plugins

maven distingue les référentiels normaux des référentiels de plugins (pluginRepository):

On peut utiliser des versions de développement des principaux plugins (fournis par la fondation apache) en utilisant un référentiel les stockant:

<pluginRepositories>
  <pluginRepository>
    <id>snapshots</id>
    <url>http://svn.apache.org/maven-snapshot-repository</url>
  </pluginRepository>
</pluginRepositories>

Installation locale

La commande  

$> mvn install
permet de "déployer" un projet dans le référentiel local, en opposition à deploy qui déploie dans le référentiel de distribution associé au projet. L'artefact est copié dans le référentiel avec son POM et son checksum.  

Pour installer directement un artefact dans le référentiel local, on peut utiliser la commande suivante :

$> mvn install:install-file -DgroupId=group-id \
                         -DartifactId=artifact-id \
                         -Dversion=version \
                         -Dpackaging=packaging \
                         -Dfile=fileToInstall

index