Maven: le meilleur moyen de lier un JAR externe personnalisé à mon projet?

151

C'est mes premiers jours à apprendre le Maven et j'ai encore du mal avec les bases. J'ai un fichier .jar externe (non disponible dans les dépôts publics) que je dois référencer dans mon projet et j'essaie de déterminer quelle est ma meilleure option.

C'est un projet à petite échelle sans référentiel central pour les bibliothèques, il doit donc être soit un référentiel local (en quelque sorte ajouté au contrôle de source, je ne sais pas s'il est censé fonctionner de cette façon?) Ou le .jar doit être stocké sur disque en dehors de tout référentiel formel.

1) Quelle est ma meilleure option pour ajouter le fichier .jar aux références de mon projet avec maven étant donné que je veux que le projet et la bibliothèque soient sous contrôle de code source?

2) Je n'arrive toujours pas à voir Eclipse voir la dépendance. Je l'ai ajouté manuellement à la section du pom, et il apparaît bien dans la liste des dépendances dans m2eclipse. mvn compile et mvn package réussissent tous les deux, mais l'exécution du programme entraîne:

Exception in thread "main" java.lang.Error: Unresolved compilation problems:
        LibraryStuff cannot be resolved to a type

C'est après avoir modifié le POM comme suit:

<dependency>
  <groupId>stuff</groupId>
  <artifactId>library</artifactId>
  <version>1.0</version>
  <systemPath>${lib.location}/MyLibrary.jar</systemPath>
  <scope>system</scope>
</dependency>

Dois-je exécuter mvn install: install-file même si j'ai déjà le pom.xml édité comme ci-dessus?

Merci!

Alexandr Kurilin
la source

Réponses:

67

Je pense que tu devrais utiliser mvn install:install-file pour remplir votre référentiel local avec les jars de la bibliothèque, puis vous devriez changer la portée du système à la compilation.

Si vous commencez avec maven, je suggère d'utiliser maven directement et non les plugins IDE, car cela ajoute une couche supplémentaire de complexité.

Quant à l'erreur, mettez-vous les fichiers jar requis sur votre chemin de classe? Si vous utilisez des types de la bibliothèque, vous devez également y avoir accès à l'exécution. Cela n'a rien à voir avec maven lui-même.

Je ne comprends pas pourquoi vous voulez mettre la bibliothèque sous contrôle de code source - c'est pour le code source et non pour les fichiers binaires.

harceleur
la source
36
pour en savoir plus mvn install::install-file: mkyong.com/maven
Doug
7
L'utilisation mvn install::install-filesur votre référentiel local signifierait que toute personne qui clonerait votre code source devrait également faire cette étape manuelle. Sinon, la construction est cassée hors de la boîte
Isen Ng
cela n'ajoutera pas le fichier jar au fichier war.
Prachi
207

Vous pouvez créer un référentiel In Project, de sorte que vous n'ayez pas à le faire run mvn install:install-filechaque fois que vous travaillez sur un nouvel ordinateur

<repository>
    <id>in-project</id>
    <name>In Project Repo</name>
    <url>file://${project.basedir}/libs</url>
</repository>

<dependency>
    <groupId>dropbox</groupId>
    <artifactId>dropbox-sdk</artifactId>
    <version>1.3.1</version>
</dependency>

/groupId/artifactId/version/artifactId-verion.jar

détail lire ce billet de blog

https://web.archive.org/web/20121026021311/charlie.cu.cc/2012/06/how-add-external-libraries-maven

Charlie Wu
la source
2
L'utilisation de la solution ci-dessus montrait un avertissement lors de l'exécution de "mvn clean package" - Le POM du projet <dependency_name> est manquant, aucune information de dépendance disponible.
Jignesh Gohel
C'est la meilleure solution pour les cas où vous devez ajouter un ou quelques fichiers jar. Merci.
Antonio Sesto
2
Ou, vous pouvez ajouter des dépendances locales directement comme dans stackoverflow.com/a/22300875/640378
mauryat
2
J'ai dû utiliser file: /// $ {project.basedir} / libs (3 barres obliques transférées) au lieu de file: // $ {project.basedir} / libs
Loc Phan
2
Si le jar en cours d'installation n'est pas un jar compilé par maven, vous devrez également ajouter un nouveau fichier pom pour définir les métadonnées. Pour vous épargner tous ces problèmes manuels, je vous recommande d'utiliser mvn install:install-file, puis de copier la structure de répertoires entière de votre référentiel local vers votre référentiel de projet.
Isen Ng
33

Cela peut être facilement réalisé en utilisant l'élément <scope> imbriqué dans l'élément <dependency>.

Par exemple:

 <dependencies>
   <dependency>
     <groupId>ldapjdk</groupId>
     <artifactId>ldapjdk</artifactId>
     <scope>system</scope>
     <version>1.0</version>
     <systemPath>${basedir}\src\lib\ldapjdk.jar</systemPath>
   </dependency>
 </dependencies>

Référence: http://www.tutorialspoint.com/maven/maven_external_dependencies.htm

Jignesh Gohel
la source
Cette méthode fonctionne très bien lorsque vous n'avez que l'Eclipse Embedded Maven et que vous n'avez pas le plugin d'installation (système hors ligne), vous ne pouvez donc pas exécuter l' installobjectif sur le projet dépendant. Ofc ayant un système airgapped et ayant tous les plugins sauf le plugin d'installation, est une situation assez rare.
Cardin Lee JH
1
Le plus propre et le plus simple.
Ajay Kumar
comment ajouter un chemin de dépendance local qui se trouve à l'extérieur du dossier $ {project.basedir}, comme je veux le chemin $ {basedir} \ src \ lib \ ldapjdk.jar 1 niveau dans un autre dossier
Naveen Kumar
Je reçois une erreur -"The POM for … is missing, no dependency information available” even though it exists in Maven Repository
garg10mai
28

Le manuel Maven dit de faire ceci:

mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar
Vladislav Rastrusny
la source
4
cette commande installe la lib dans votre repo maven. L'inconvénient est que si vous essayez de travailler sur un projet sur un autre ordinateur, vous devez l'exécuter à nouveau.
Charlie Wu
25

update Nous venons depuis d'installer notre propre serveur Nexus, beaucoup plus simple et plus propre.

Dans notre entreprise, nous avions des fichiers jar dont certains étaient communs mais qui n'étaient hébergés dans aucun référentiel maven, et nous ne voulions pas non plus les avoir dans le stockage local. Nous avons créé un repo mvn (public) très simple sur Github (mais vous pouvez l'héberger sur n'importe quel serveur ou localement):
notez que ce n'est idéal que pour gérer quelques fichiers jar rarement modifiés

  1. Créez un dépôt sur GitHub:
    https://github.com/<user_name>/mvn-repo/

  2. Ajouter un référentiel dans pom.xml
    (notez que le chemin complet du fichier brut sera un peu différent du nom du référentiel )

    <repository>
        <id>project-common</id>
        <name>Project Common</name>
        <url>https://github.com/<user_name>/mvn-repo/raw/master/</url>
    </repository>
  3. Ajouter une dépendance à l'hôte (Github ou serveur privé)
    a. Tout ce que vous devez savoir, c'est que les fichiers sont stockés dans le modèle mentionné par @glitch
    /groupId/artifactId/version/artifactId-version.jar
    b. Sur votre hôte, créez les dossiers correspondant à ce modèle.
    c'est-à-dire que si vous avez un fichier jar nommé service-sdk-0.0.1.jar, créez le dossier service-sdk/service-sdk/0.0.1/et placez-y le fichier jar service-sdk-0.0.1.jar.
    c. Testez-le en essayant de télécharger le fichier jar depuis un navigateur (dans notre cas:https://github.com/<user_name>/mvn-repo/raw/master/service-sdk/service-sdk/0.0.1/service-sdk-0.0.1.jar

  4. Ajoutez une dépendance à votre fichier pom.xml:

    <dependency>
        <groupId>service-sdk</groupId>
        <artifactId>service-sdk</artifactId>
        <version>0.0.1</version>
    </dependency>
  5. Prendre plaisir

Kenny Cason
la source
bien, c'est la solution la plus évolutive que j'ai trouvée, merci
Charlie Wu
11

N'utilisez pas systemPath. Contrairement à ce que les gens ont dit ici, vous pouvez placer un fichier jar externe dans un dossier sous le répertoire de votre projet extrait et ne pas le trouver comme d'autres dépendances. Voici deux étapes cruciales:

  1. Utilisez "mvn install: install-file" avec -DlocalRepositoryPath.
  2. Configurez un référentiel pour qu'il pointe vers ce chemin dans votre POM.

C'est assez simple et vous pouvez trouver un exemple étape par étape ici: http://randomizedsort.blogspot.com/2011/10/configuring-maven-to-use-local-library.html

Nehc
la source
8

Méthode Maven pour ajouter des pots non Maven au projet Maven

Projet Maven et pots non maven

Ajoutez les plugins d'installation maven dans votre section de construction

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-install-plugin</artifactId>
        <version>${version.maven-install-plugin}</version>
        <executions>

            <execution>
                <id>install-external-non-maven1-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar1.group</groupId>
                    <artifactId>non-maven1</artifactId>
                    <version>${version.non-maven1}</version>
                    <file>${project.basedir}/libs/non-maven1.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
            <execution>
                <id>install-external-non-maven2-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar2.group</groupId>
                    <artifactId>non-maven2</artifactId>
                    <version>${version.non-maven2}</version>
                    <file>${project.basedir}/libs/non-maven2.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
            <execution>
                <id>install-external-non-maven3-jar</id>
                <phase>clean</phase>
                <configuration>
                    <repositoryLayout>default</repositoryLayout>
                    <groupId>jar3.group</groupId>
                    <artifactId>non-maven3</artifactId>
                    <version>${version.non-maven3}</version>
                    <file>${project.basedir}/libs/non-maven3.jar</file>
                    <packaging>jar</packaging>
                    <generatePom>true</generatePom>
                </configuration>
                <goals>
                    <goal>install-file</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

Ajouter la dépendance

<dependencies>
    <dependency>
        <groupId>jar1.group</groupId>
        <artifactId>non-maven1</artifactId>
        <version>${version.non-maven1}</version>
    </dependency>
    <dependency>
        <groupId>jar2.group</groupId>
        <artifactId>non-maven2</artifactId>
        <version>${version.non-maven2}</version>
    </dependency>
    <dependency>
        <groupId>jar3.group</groupId>
        <artifactId>non-maven3</artifactId>
        <version>${version.non-maven3}</version>
    </dependency>
</dependencies>

Références Note Je suis le propriétaire du blog

artisanat
la source
Comment connais-tu les versions des fichiers JAR et du plugin d'installation maven?
osk
les versions des jars sont juste constituées, les versions du plugin d'installation de maven sont les dernières
craftmannadeem
7

Si vous rencontrez le même problème et que vous utilisez spring-boot v1.4 + , vous pouvez le faire de cette manière.

Il existe un includeSystemScope que vous pouvez utiliser pour ajouter des dépendances de portée système au fichier jar.

par exemple

J'utilise le pilote oracle dans mon projet.

<dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc14</artifactId>
        <version>10.2.0.3.0</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/src/main/resources/extra-jars/ojdbc14-10.2.0.3.0.jar</systemPath>
    </dependency>

puis faites includeSystemScope = true pour inclure le fichier jar dans le chemin / BOOT-INF / lib / **

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <includeSystemScope>true</includeSystemScope>
    </configuration>
</plugin>

et exclure de la ressource pour éviter les doublons incluent, le pot est assez gros ~

<build>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>**/*.jar</exclude>
            </excludes>
        </resource>
    </resources>
</build>

Bonne chance!

chendu
la source
Je cherchais une solution comme celle-ci, tout simplement parce que lorsqu'un nouveau développeur arrive, cela simplifie la procédure d'installation. Lorsque vous n'avez pas de serveur artificiel, il est plus facile d'avoir la dépendance personnalisée dans votre projet. De plus, lorsque vous utilisez un CI, cette solution évite d'installer manuellement le fichier jar sur le serveur CI.
Dalc
Que diriez-vous de plusieurs pots ??
mithun_ghose
4

Changez votre systemPath .

<dependency>
  <groupId>stuff</groupId>
  <artifactId>library</artifactId>
  <version>1.0</version>
  <systemPath>${project.basedir}/MyLibrary.jar</systemPath>
  <scope>system</scope>
</dependency>
Aung Myat Hein
la source
3

Le pom.xml va regarder votre référentiel local pour essayer de trouver la dépendance qui correspond à votre artefact. De plus, vous ne devriez pas vraiment utiliser la portée du système ou les attributs systemPath, ils sont normalement réservés aux éléments qui se trouvent dans le JDK et non dans le JRE.

Consultez cette question pour savoir comment installer les artefacts maven.

Tim Sparg
la source
3

Notez que tous les exemples qui utilisent

<repository>...</respository> 

exiger externe

<repositories>...</repositories> 

balises englobantes. Ce n'est pas clair d'après certains des exemples.


la source
2

La meilleure solution ici est d'installer un référentiel: Nexus ou Artifactory. Si vous donne un endroit pour mettre des choses comme ça, et plus loin, cela accélère les choses en mettant en cache vos affaires de l'extérieur.

Si la chose dont vous avez affaire est open source, vous pouvez également envisager de mettre en central.

Consultez le guide .

bmargulies
la source
1

Avec Eclipse Oxygen, vous pouvez faire les choses ci-dessous:

  1. Placez vos bibliothèques dans WEB-INF / lib
  2. Projet -> Configurer le chemin de construction -> Ajouter une bibliothèque -> Bibliothèque d'applications Web

Maven les prendra lors de l'installation du projet.

Meule
la source
3
Si je le fais, les autres utilisateurs qui tirent mon projet doivent-ils faire de même dans Eclipse?
cruxi
0

Si le fichier jar externe est créé uniquement par un projet Maven, vous pouvez copier l'intégralité du projet sur votre système et exécuter un

mvn install

dans le répertoire du projet. Cela ajoutera le fichier jar dans le répertoire .m2 qui est le référentiel maven local.

Vous pouvez maintenant ajouter le

<dependency>
     <groupId>copy-from-the=maven-pom-of-existing-project</groupId>
     <artifactId>copy-from-the=maven-pom-of-existing-project</artifactId>
     <version>copy-from-the=maven-pom-of-existing-project</version>
</dependency>

Cela garantira que vous

mvn exec:java 

travaux. Si vous utilisez suggéré ici

<scope>system</scope>

Ensuite, vous devrez ajouter des classes individuellement tout en utilisant l'exécution via la ligne de commande.

Vous pouvez ajouter les fichiers JAR externes à l'aide de la commande suivante décrite ici

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> \
-DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>
Tueur de bogues
la source
0

Le moyen le plus efficace et le plus propre que j'ai trouvé pour résoudre ce problème est d'utiliser les packages Github

  1. Créez un simple référentiel public / privé vide sur GitHub selon vos besoins, que vous souhaitiez que votre jar externe soit hébergé publiquement ou non.

  2. Exécutez la commande ci-dessous maven pour déployer votre fichier jar externe dans le référentiel github créé ci-dessus

    mvn deploy:deploy-file \ -DgroupId= your-group-id \ -DartifactId= your-artifact-id \ -Dversion= 1.0.0 -Dpackaging= jar -Dfile= path-to-file \ -DrepositoryId= id-to-map-on-server-section-of-settings.xml \ -Durl=https://maven.pkg.github.com/github-username/github-reponame-created-in-above-step

    La commande ci-dessus déploiera votre fichier jar externe dans le référentiel GitHub mentionné dans -Durl=. Vous pouvez consulter ce lien sur Comment déployer des dépendances en tant que packages GitHub Tutoriel de déploiement de packages GitHub

  3. Après cela, vous pouvez ajouter la dépendance en utilisant groupId, artifactIdet versionmentionné à l'étape ci-dessus dans maven pom.xmlet exécutermvn install

  4. Maven récupérera la dépendance du fichier jar externe à partir du registre des packages GitHub et fournira dans votre projet maven.

  5. Pour que cela fonctionne, vous devrez également configurer vos mavens pour settings.xmlqu'ils récupèrent à partir du registre de packages GitHub.

Nitish Kumar
la source