Documentations > Création de repository local avec Maven
Comment créer un repository local avec Maven ?
Table des matières
- Paramétrage du projet
- Installation d’une librairie (package) dans votre projet via le terminal ?
- Décompresser la ou les librairies
- S’assurer que la commande mvn est dans le path Windows
- Installer la librairie
- Comment lier le projet Java avec la librairie contenue dans le repository local ?
- Bonus, comment automatiser l’installation de toutes les librairies d’un dossier dans notre repository local ?
- Exécuter des commandes cmd en Python
- Récupérer le nom des fichiers présents afin d'extraire un groupId et un artifactId
- Exemple de nommage de librairies
- Définir des conventions de nommage pour vos librairies
- Vers une convention de nommage officielle ?
- Utiliser le chemin de dossier le plus commun comme nom de groupId
- Code complet de l'automatisation d'installation et de nommage
- Liens externes et sujets connexes
Lorsqu’on fait un projet Java, parfois les librairies que nous souhaitons ajouter ne sont pas disponibles directement sur le serveur par défaut Maven 2. Il faut alors mettre en place un repository local afin de pouvoir accéder aux librairies du projet. On peut aussi mettre ses librairies sur un serveur distant, comme un serveur JfrogArtifactory. Mais dans cette documentation, je vais vous présenter comment mettre en place un repository Maven en local.
Paramétrage du projet
Je vais utiliser IntelliJ IDEA Community Edition. Mais si vous souhaitez créer votre projet Maven de toutes pièces, je vous invite à suivre le tutoriel officiel.
Créez votre projet et choisissez le bon JDK, celui qui fonctionnera avec vos librairies


Installation d’une librairie (package) dans votre projet via le terminal
Téléchargez vos librairies. J’ai téléchargé deux librairies : android-junit-report-1.2.6 et javax.
1. Décompresser vos librairies


2. S’assurer que la commande mvn est dans le path Windows
- Ajoutez une nouvelle ligne dans la variable path de vos variables système en suivant les étapes. Ajoutez-y le chemin vers votre dossier bin de Maven /maven/lib/maven3/bin.
Exemple : - Suivez les étapes indiquées par les numéros sur les captures d'écran
- Vérifiez que le lien avec Maven fonctionne dans un terminal sur votre IDE ou bien sur Windows (CMD) avec la commande mvn -v
Plaintext
C:\cheminVerVotreInstallationIntteliJ\IntelliJ IDEA Community Edition 2024.3\plugins\maven\lib\maven3\bin




3. Installer la librairie
- Modifier la commande avec votre déclaration de librairie, exemple :
- Après avoir entré la commande, vous devriez avoir un log comme celui-ci si tout fonctionne correctement :
bash
mvn install:install-file
-Dfile=<path-to-file>
-DgroupId=<group-id>
-DartifactId=<artifact-id>
-Dversion=<version>
-Dpackaging=<packaging>
-DgeneratePom=true
La commande à exécuter dans un terminal ressemble à ceci : La variable -Dfile pour le chemin jusqu’au fichier .jar. -DgroupId c’est l’identifiant unique de la librairie dans le projet. -DartifactId c'est le nom spécifique du projet ou module au sein du groupId. -Dversion c’est la version de la librairie, une suite de chiffres entrecoupée de points. S’il n’y en a pas, vous pouvez mettre '1.0' par exemple. -Dpackaging=jar c’est le format dans lequel est votre fichier à installer.
bash
mvn install:install-file -Dfile=C:\maven-libraries\android-junit-report-1.2.6.jar -DgroupId=com.android.tools -DartifactId=android-junit-report -Dversion=1.2.6 -Dpackaging=jar -DgeneratePom=true
Plaintext
[INFO] Scanning for projects... [INFO] [INFO] ------------------< org.apache.maven:standalone-pom >------------------- [INFO] Building Maven Stub Project (No POM) 1 [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] --- install:3.1.2:install-file (default-cli) @ standalone-pom --- [INFO] pom.xml not found in android-junit-report-1.2.6.jar [INFO] Installing C:\cheminVersVotreFichierPointJar\documentation-local-repository\jars\android-junit-report-1.2.6.jar to C: \cheminVersVotreFichierPointJar\documentation-local-repository\create-a-local-repository\local-repository\android-junit-report\android-junit-report\1.2.6\android-junit-report-1.2.6.jar [INFO] Installing C:\Users\USERSI~1\AppData\Local\Temp\mvninstall5133595932557109365.pom to C:\cheminVersVotreFichierPointJar\documentation-local-repository\create-a-local-repository\local-repository\android-junit-report\android-junit-report\1.2.6\android-junit-report-1.2.6.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.874 s [INFO] Finished at: 2024-11-15T16:39:21+01:00 [INFO] ------------------------------------------------------------------------
Sinon, il faudra regarder erreur par erreur. Généralement, c’est le chemin qui ne correspond pas parfaitement. Ou la commande qui est mal formatée. On peut par exemple éviter les espaces dans les dossiers utilisés. Exemple de nom de dossier : Dossier projet, faire plutôt dossier-projet ou dossier_projet.
Comment lier le projet Java avec la librairie contenue dans le repository local ?
1. Déclaration du repository et celle du package
- Déclarer le repository
- Ajouter la définition du package précédemment installé
xml
<repositories>
<repository>
<id>local-repo</id>
<url>file://${basedir}/local-repository/</url>
</repository>
</repositories>
On déclare le repository dans le pom.xml à la racine du projet : file://${basedir}/ assurant la portabilité de la librairie. Les librairies sont dans le dossier /local-repository/ qui est à créer. C’est plus simple lorsque vous souhaitez transformer votre projet en FAT JAR.
xml
<dependencies>
<dependency>
<groupId>android.junit.report</groupId>
<artifactId>junitreport</artifactId>
<version>1.2.6</version>
<scope>compile</scope>
</dependency>
</dependencies>
2. Synchroniser le projet Maven
Vous pouvez utiliser les outils d’IntelliJ ou votre IDE pour faire la synchronisation des librairies de votre projet.


Ou vous pouvez faire un mvn clean install. La librairie devrait être visible dans vos dossiers de projets d’IntelliJ. Vous pouvez aussi essayer d’importer le fichier qu’il vous faut pour voir si le projet compile.
Pour aller plus loin, comment automatiser plusieurs installations de librairies dans un repository local ?
Le processus d’installation des librairies est très chronophage, c’est pourquoi je conseille un script. Via Python, nous pouvons parcourir le dossier rempli des librairies du projet à installer. Ensuite, une par une, via la commande CMD vue précédemment, nous les installons. Enfin, on crée une déclaration de la dépendance à copier-coller.
- Positionner vos fichiers .jar au même endroit :

1. Exécuter des commandes CMD en Python
Python
import os
retour_commande = os.popen(r'mvn install:install-file -Dfile="<leCheminDuFichierJar>" -DgroupId="votreNomDeGroupeId" -DartifactId="votreArtifactId" -Dversion="laVersionDeLartifact" -Dpackaging=jar -DlocalRepositoryPath="cheminVersLeRepositoryFinal"')
print(retour_commande)
La commande est exécutée en CMD et vous récupérez le résultat de la commande via l'affichage en console du print(retour_commande).
2. Récupérer le nom des fichiers présents afin d'extraire un groupId et un artifactId.
Python
import os
for root, dirs, files in os.walk("leCheminDuDossierVersLesFichiersJar"):
for file in files :
artifactId= ".".join(file.split("-")[:-1])
print(artifactId)
version = ".".join((file.split("-")[-1]).split(".")[:-1])
print(version)
Ce code très factorisé permet de récupérer l’artifactId et la version contenue dans le nom du fichier en deux lignes s'il est au bon format, exemple : "ma-librairie-2.3".
Python
import os
for root, dirs, files in os.walk("leCheminDuDossierVersLesFichiersJar"):
for file in files :
fichier = file.split("-")
version = fichier[len(fichier)-1].split(".")
artifactId = ""
for i in range(0,len(fichier)-1) :
if i == 0 :
artifactId = fichier[i]
else:
artifactId = artifactId+"."+ fichier[i]
version_full = ""
for i in range(0,len(version)-1) :
if i == 0 :
version_full = version[i]
else:
version_full = version_full+"."+ version[i]
print(artifactId)
print(version_full)
Une version non factorisée de ce code mais avec des boules et des conditions.
3. Exemple de nommage de librairies
Python
import os
for root, dirs, files in os.walk("leCheminDuDossierVersLesFichiersJar"):
for file in files :
artifactId= ".".join(file.split("-")[:-1])
print(artifactId)
version = ".".join((file.split("-")[-1]).split(".")[:-1])
print(version)
retour_commande = os.popen(r'mvn install:install-file -Dfile="leCheminDuDossierVersLesFichiersJar" -DgroupId="'+artifactId+'" -DartifactId="'+artifactId+'" -Dversion="'+version+'" -Dpackaging=jar -DlocalRepositoryPath="cheminVersLeRepositoryFinal"')
print(retour_commande)
Le résultat serait :
- groupId = android.junit.report
- artifactId = android.junit.report
- version = 1.2.6
Ce n’est pas un nom standard, mais cela permet à Maven de récupérer le module et de le rendre accessible ensuite en utilisant la déclaration :
xml
<dependency>
<groupId>android-junit-report</groupId>
<artifactId>android-junit-report</artifactId>
<version>1.2.6</version>
<scope>compile</scope>
</dependency>
N’oubliez pas de faire une synchronisation comme pour Synchroniser le projet Maven. Deux manières de vérifier : soit en faisant un control-click sur le nom de votre artifactId dans votre pom.xml avec IDEA IntelliJ. Cela vous mène au fichier .pom de la librairie. Vous pouvez aussi mettre un import, pour mon exemple : import com.zutubi.android.junitreport.*; dans votre main.java et voir si cela compile.
4. Définir des conventions de nommage pour vos librairies
Vos librairies ont parfois une même racine, comme perf4j, org, be, etc. Vous pouvez mettre en place un filtre pour rendre plus cohérentes vos méthodes de déclaration.
Python
premier_mot = file.split("-")[0]
if (premier_mot == "perf4j") :
retour_commande = os.popen(r'mvn install:install-file -Dfile='+DfileRacine + file+' -DgroupId="org.perf4j" -DartifactId="'+artifactId+'" -Dversion="'+version+'" -Dpackaging=jar '+DlocalRepositoryPath).read()
print(retour_commande)
- On y ajoute à la fin la possibilité de faire la saisie à la main pour les cas particuliers.
- Un exemple du code complet serait :
Python
else :
print(file)
print("GroupId : ")
saisieGid = input()
print("ArtifactId : ")
saisieAid = input()
retour_commande = os.popen(r'mvn install:install-file -Dfile='+DfileRacine + file+' -DgroupId="'+saisieGid+'" -DartifactId="'+saisieAid+'" -Dversion="'+version+'" -Dpackaging=jar '+DlocalRepositoryPath).read()
print(retour_commande)
Python
import os
DfileRacine = r'C:/cheminVersFichiersJars/documentation-local-repository/jars/'
DlocalRepositoryPath = r'-DlocalRepositoryPath=C:/cheminVersLeRepository/create-a-local-repository/local-repository/'
liste_des_definition_pom_xml = []
def pomXmlGenerationDef(groupId, artifactId, version) :
liste_des_definition_pom_xml.append("<dependency>\n <groupId>"+groupId+"</groupId>\n <artifactId>"+artifactId+"</artifactId>\n <version>"+version+"</version>\n <scope>compile</scope>\n</dependency>")
def affichageListeDesDefinitionPomXml() :
for dependence in liste_des_definition_pom_xml :
print(dependence)
for root, dirs, files in os.walk(DfileRacine):
for file in files :
artifactId= ".".join(file.split("-")[:-1])
print(artifactId)
version = ".".join((file.split("-")[-1]).split(".")[:-1])
print(version)
premier_mot = file.split("-")[0]
if (premier_mot == "perf4j") :
retour_commande = os.popen(r'mvn install:install-file -Dfile='+DfileRacine + file+' -DgroupId="org.perf4j" -DartifactId="'+artifactId+'" -Dversion="'+version+'" -Dpackaging=jar '+DlocalRepositoryPath).read()
print(retour_commande)
elif (premier_mot == "opensaml") :
print("opensaml")
retour_commande = os.popen(r'mvn install:install-file -Dfile='+DfileRacine + file+' -DgroupId="org.opensaml" -DartifactId="'+artifactId+'" -Dversion="'+version+'" -Dpackaging=jar '+DlocalRepositoryPath).read()
print(retour_commande)
pomXmlGenerationDef("org.opensaml", artifactId, version)
else :
print(file)
print("GroupId : ")
saisieGid = input()
print("ArtifactId : ")
saisieAid = input()
retour_commande = os.popen(r'mvn install:install-file -Dfile='+DfileRacine + file+' -DgroupId="'+saisieGid+'" -DartifactId="'+saisieAid+'" -Dversion="'+version+'" -Dpackaging=jar '+DlocalRepositoryPath).read()
print(retour_commande)
affichageListeDesDefinitionPomXml()
print("Installation terminée ! Tous les fichiers JAR ont été lus.")
Cela rend les déclarations plus lisibles si vos filtres sont précis. Le code permet l'installation avec des nommages presque tous automatisés. Et l'affichage en console via affichageListeDesDefinitionPomXml() qui vous permet de copier-coller les déclarations dans le pom.xml. Faites une synchronisation après l'ajout des nouvelles déclarations (Synchroniser le projet Maven).
Vers une convention de nommage officielle ?
1. Utiliser le chemin de dossier le plus commun comme nom de groupId
Python
def extract_group_id_from_jar(jar_path):
with zipfile.ZipFile(jar_path, 'r') as jar:
# Récupérer les chemins des fichiers .class dans le JAR
class_file_paths = [f for f in jar.namelist() if f.endswith(".class")]
# Extraire les chemins des packages racines (éviter META-INF)
valid_package_paths = [
f.rsplit("/", 1)[0] for f in class_file_paths
if "/" in f and not f.startswith("META-INF")
]
# Si aucun package valide n'est trouvé, lever une exception
if not valid_package_paths:
raise ValueError("Aucun package valide trouvé dans les fichiers .class")
# Identifier le package racine le plus fréquent
most_common_package = Counter(valid_package_paths).most_common(1)[0][0]
return most_common_package.replace("/", ".")
La librairie Counter nous permet ici d'identifier les chemins les plus fréquents. On peut, en récupérant tous les chemins menant à un .class émettre l'hypothèse que le chemin le plus peuplé de .class est le chemin le plus proche de la convention de nommage officielle des packages Maven. Dans mon exemple, la suite de dossiers la plus peuplée de .class est
2. Code complet de l'automatisation d'installation et de nommage
Pour mettre en marche le script, reprenez chaque étape :
- Téléchargez vos librairies.
- Mettez les .jar dans un seul dossier.
- Créez un projet Maven.
- Créez un dossier pour votre repository à la racine du projet.
- Modifier la variable : DfileRacine par le chemin où se trouvent vos .jar. Mettez des / et non des \ pour votre chemin.
- Modifier la variable : DlocalRepositoryPath par le chemin où se trouve votre repository local. Mettez des / et non des \ pour votre chemin.
- Exécuter le code Python.
- Copier-coller les dépendances affichées dans le terminal dans votre pom.xml à la racine.
- Refaites une synchronisation du projet.
- Importer et utiliser les librairies du repository local.
Python
import re, os, zipfile
from collections import Counter
# Fonction pour extraire le groupId à partir du fichier JAR
def extract_group_id_from_jar(jar_path):
with zipfile.ZipFile(jar_path, 'r') as jar:
# Récupérer les chemins des fichiers .class dans le JAR
class_file_paths = [f for f in jar.namelist() if f.endswith(".class")]
# Extraire les chemins des packages racines (éviter META-INF)
valid_package_paths = [
f.rsplit("/", 1)[0] for f in class_file_paths
if "/" in f and not f.startswith("META-INF")
]
# Si aucun package valide n'est trouvé, lever une exception
if not valid_package_paths:
raise ValueError("Aucun package valide trouvé dans les fichiers .class")
# Identifier le package racine le plus fréquent
most_common_package = Counter(valid_package_paths).most_common(1)[0][0]
return most_common_package.replace("/", ".")
# Fonction pour extraire l'artifactId et la version à partir du nom du fichier JAR
def extract_artifact_id_and_version_from_filename(jar_path):
# Extraire le nom du fichier JAR sans son chemin
jar_filename = jar_path.rsplit("/", 1)[-1]
# Retirer l'extension du fichier .jar
base_filename = jar_filename.rsplit(".", 1)[0]
# Séparer le nom du fichier sur le dernier tiret pour obtenir artifactId et version
parts = base_filename.rsplit("-", 1)
# Pattern vérifiant que c'est une suite de chiffre et de point à la fin du split du nom de fichier
pattern = r"\b\d+(\.\d+)*\b"
# Si le nom du fichier est en "unSeulMot" et non "unversion-1.0" ou ne possède pas de chiffre à la dernière position "un-mot" alors assigne la version à undifined.
if len(parts) <= 2 or not re.search(pattern, parts[len(parts)-1]) :
artifact_id = base_filename # Tout le nom est l'artifactId
version = "undefined" # Pas de version détectée
else :
artifact_id, version = parts # On prends la artifact_id de la position 0 du tableau et version position 1.
return [artifact_id, version]
# Fonction pour générer la dépendance Maven en XML à partir du JAR
def get_groupid_artifactid_version(jar_path):
group_id, artifact_id, version = "", "", ""
if os.path.exists(jar_path) :
# Extraire l'artifactId, la version et le groupId à partir du JAR
artifact_id, version = extract_artifact_id_and_version_from_filename(jar_path)
group_id = extract_group_id_from_jar(jar_path)
else :
print(r'Le chemin : "'+ jar_path + r'" est inconnu du système.')
return [group_id, artifact_id, version]
## Commande cmd de configuration des jar version Maven ##
DfileRacine = r'C:/cheminVersVosFichiesJars/jars/' # Position de vos jars dans votre système de fichiers
DlocalRepositoryPath = r'-DlocalRepositoryPath=C:/cheminVersVotreRepositoryLocal/local-repository/' # Position de votre repository local
# Liste d'affichage des déclarations à copier coller à la fin dans votre pom.xml
liste_des_definition_pom_xml = []
# Mise en forme d'une déclaration de dépendance
def pomXmlGenerationDef(groupId, artifactId, version) :
liste_des_definition_pom_xml.append("<dependency>\n <groupId>"+groupId+"</groupId>\n <artifactId>"+artifactId+"</artifactId>\n <version>"+version+"</version>\n <scope>compile</scope>\n</dependency>")
# Affichage dans le termine des définitions de dépendance pour le copier coller
def affichageListeDesDefinitionPomXml() :
for dependence in liste_des_definition_pom_xml :
print(dependence)
# Parcourir les fichiers au chemin DfileRacine.
for file in os.listdir(DfileRacine):
# N'exécuter les installations seulement sur les fichiers .jar
if os.path.isfile(os.path.join(DfileRacine, file)) and file.endswith('.jar'):
group_id, artifact_id, version = get_groupid_artifactid_version(DfileRacine + file)
# Si les variables sont vides, c'est qu'il y a eu un problème avec le nom du fichier.
if group_id != "" and artifact_id != "" and version != "" :
retour_commande = os.popen(r'mvn install:install-file -Dfile='+DfileRacine + file+' -DgroupId="'+group_id+'" -DartifactId="'+artifact_id+'" -Dversion="'+version+'" -Dpackaging=jar '+DlocalRepositoryPath).read()
print(retour_commande)
pomXmlGenerationDef(group_id, artifact_id, version)
else :
print("Le fichier : "+file+ " n'a pas pu être traité ! Renommez-le au format 'nom-du-package' si pas de version ou 'nom-du-package-2.1.2'.' ")
affichageListeDesDefinitionPomXml()
print("Installation terminée ! Tous les fichiers JAR ont été lus.")