Maven: ajouter une dépendance à un pot par chemin relatif

232

J'ai un pot propriétaire que je veux ajouter à mon pom en tant que dépendance.

Mais je ne veux pas l'ajouter à un référentiel. La raison en est que je veux que mes commandes maven habituelles telles que mvn compile, etc., fonctionnent hors de la boîte. (Sans demander aux développeurs de l'ajouter à un référentiel par eux-mêmes).

Je veux que le pot soit dans une lib 3rdparty dans le contrôle de code source et que je le lie par chemin relatif depuis le fichier pom.xml.

Cela peut-il être fait? Comment?

fil volant
la source

Réponses:

343

Je veux que le pot soit dans une lib 3rdparty dans le contrôle de code source et que je le lie par chemin relatif depuis le fichier pom.xml.

Si vous le voulez vraiment (comprenez, si vous ne pouvez pas utiliser un référentiel d'entreprise), alors mon conseil serait d'utiliser un "référentiel de fichiers" local au projet et de ne pas utiliser une systemdépendance de portée. La systemportée doit être évitée, de telles dépendances ne fonctionnent pas bien dans de nombreuses situations (par exemple dans l'assemblage), elles causent plus de problèmes que d'avantages.

Donc, au lieu de cela, déclarez un référentiel local au projet:

<repositories>
  <repository>
    <id>my-local-repo</id>
    <url>file://${project.basedir}/my-repo</url>
  </repository>
</repositories>

Installez votre bibliothèque tierce là-dedans en utilisant install:install-filele localRepositoryPathparamètre:

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
                         -DartifactId=<myArtifactId> -Dversion=<myVersion> \
                         -Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

Mise à jour: Il semble que l' install:install-fileignore localRepositoryPathlors de l'utilisation de la version 2.2 du plugin. Cependant, cela fonctionne avec la version 2.3 et ultérieure du plugin. Utilisez donc le nom complet du plugin pour spécifier la version:

mvn org.apache.maven.plugins:maven-install-plugin:2.3.1:install-file \
                         -Dfile=<path-to-file> -DgroupId=<myGroup> \ 
                         -DartifactId=<myArtifactId> -Dversion=<myVersion> \
                         -Dpackaging=<myPackaging> -DlocalRepositoryPath=<path>

documentation de maven-install-plugin

Enfin, déclarez-le comme toute autre dépendance (mais sans la systemportée):

<dependency>
  <groupId>your.group.id</groupId>
  <artifactId>3rdparty</artifactId>
  <version>X.Y.Z</version>
</dependency>

C'est à mon humble avis une meilleure solution que d'utiliser une systemportée car votre dépendance sera traitée comme un bon citoyen (par exemple, elle sera incluse dans un assemblage, etc.).

Maintenant, je dois mentionner que la "bonne façon" de faire face à cette situation dans un environnement d'entreprise (peut-être pas le cas ici) serait d'utiliser un référentiel d'entreprise.

Pascal Thivent
la source
2
C'est une excellente idée, mais sur Maven 2.2.1, le plugin d'installation semble ignorer localRepositoryPath...
Jake
1
Pourquoi déclarer un dépôt local? Pourquoi ne pas simplement le laisser entrer dans ~ / .m2 / avec le reste.
Leif Gruenwoldt
6
@ leif81 Parce qu'alors le dépôt et les bibliothèques sont archivés dans le référentiel SCM -> Quiconque effectue une extraction de source a tout ce dont il a besoin pour créer une copie de la bibliothèque / application.
Dark Android
6
J'ai eu le même problème que @lemon, que j'ai résolu en le faisant basedir/./my-local-repoavec un seul à la .place.
Brian
2
L'emballage doit être en pot, donc -Emballage = pot
Danila Piatov
127

Utilisation de la systemportée. ${basedir}est le répertoire de votre pom.

<dependency>
    <artifactId>..</artifactId>
    <groupId>..</groupId>
    <scope>system</scope>
    <systemPath>${basedir}/lib/dependency.jar</systemPath>
</dependency>

Cependant, il est conseillé d'installer votre bocal dans le référentiel et de ne pas le valider dans le SCM - après tout, c'est ce que maven essaie d'éliminer.

Bozho
la source
15
Le système de portée doit être évité partout où cela est possible. Installer le JAR dans le référentiel est une meilleure solution ...
Gandalf StormCrow
14
oui, si possible. il a dit explicitement qu'il ne voulait pas le mettre dans le référentiel. J'ai ajouté un commentaire pour souligner que ce n'est pas une bonne pratique. Mais, il fonctionne.
Bozho
groovy, votre solution est la plus acceptable jusqu'à présent, je suppose .. J'ai totalement mal lu la question
fourmi
Oui - la question elle-même exclut la meilleure réponse. Tout mettre dans votre serveur de contrôle à source unique n'a pas grand-chose à voir avec la «construction prête à l'emploi»; au contraire, tout doit simplement être «contrôlé». Effectuez l'archivage des pom's & settings.xml (pointant vers le référentiel interne ) et utilisez deux serveurs pour votre projet: (1) contrôle de source, (2) contrôle d'artefact généré. Il est à peu près aussi logique de vérifier les fichiers jars que de vérifier les fichiers dll (mon ancien corp a en fait fait les fichiers jars & lib.a / .so / .dll's. travail quotidien. Problème résolu?
michael
est-il possible de spécifier un répertoire contenant des pots à la place afin que nous n'ayons pas à ajouter chacun comme Gradle peut le faire?
Dean Hiller
29

Ceci est une autre méthode en plus de ma réponse précédente sur Puis-je ajouter des fichiers jars à maven 2 build classpath sans les installer?

Cela contournera la limite lors de l'utilisation de versions multi-modules, en particulier si le fichier JAR téléchargé est référencé dans des projets enfants en dehors du parent. Cela réduit également le travail d'installation en créant les fichiers POM et SHA1 dans le cadre de la génération. Il permet également au fichier de résider n'importe où dans le projet sans fixer les noms ou suivre la structure du référentiel maven.

Cela utilise le plugin maven-install-plugin. Pour que cela fonctionne, vous devez configurer un projet multi-modules et avoir un nouveau projet représentant la génération pour installer les fichiers dans le référentiel local et vous assurer qu'il est le premier.

Votre projet multi-module pom.xml ressemblerait à ceci:

<packaging>pom</packaging>
<modules>
<!-- The repository module must be first in order to ensure
     that the local repository is populated -->
    <module>repository</module>
    <module>... other modules ...</module>
</modules>

Le fichier repository / pom.xml contiendra alors les définitions pour charger les fichiers JAR qui font partie de votre projet. Voici quelques extraits du fichier pom.xml.

<artifactId>repository</artifactId>
<packaging>pom</packaging>

L'emballage pom empêche cela de faire des tests ou de compiler ou de générer un fichier jar. La viande du pom.xml se trouve dans la section de construction où le plugin maven-install est utilisé.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <executions>
                <execution>
                        <id>com.ibm.db2:db2jcc</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>install-file</goal>
                        </goals>
                        <configuration>
                            <groupId>com.ibm.db2</groupId>
                            <artifactId>db2jcc</artifactId>
                            <version>9.0.0</version>
                            <packaging>jar</packaging>
                            <file>${basedir}/src/jars/db2jcc.jar</file>
                            <createChecksum>true</createChecksum>
                            <generatePom>true</generatePom>
                        </configuration>
                </execution>
                <execution>...</execution>
            </executions>
        </plugin>
    </plugins>
</build>

Pour installer plusieurs fichiers, ajoutez simplement plus d'exécutions.

Archimedes Trajano
la source
C'est la seule chose qui a fonctionné pour mon projet multi-module. L'approche <repository> locale pour une raison inconnue n'a pas fonctionné. Donc merci!
Lonzak
10

Cela fonctionne pour moi: disons que j'ai cette dépendance

<dependency>
    <groupId>com.company.app</groupId>
    <artifactId>my-library</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/my-library.jar</systemPath>
</dependency>

Ensuite, ajoutez manuellement le chemin de classe pour votre dépendance système comme ceci

<Class-Path>libs/my-library-1.0.jar</Class-Path>

Configuration complète:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifestEntries>
                <Build-Jdk>${jdk.version}</Build-Jdk>
                <Implementation-Title>${project.name}</Implementation-Title>
                <Implementation-Version>${project.version}</Implementation-Version>
                <Specification-Title>${project.name} Library</Specification-Title>
                <Specification-Version>${project.version}</Specification-Version>
                <Class-Path>libs/my-library-1.0.jar</Class-Path>
            </manifestEntries>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.company.app.MainClass</mainClass>
                <classpathPrefix>libs/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/libs/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
RufusSC2
la source
9

J'ai déjà écrit sur un modèle pour ce faire.

Elle est très similaire à la solution proposée par Pascal, bien qu'elle déplace toutes ces dépendances dans un module de référentiel dédié afin que vous n'ayez pas à la répéter partout où la dépendance est utilisée s'il s'agit d'une construction multi-modules.

Brett Porter
la source
6

Fondamentalement, ajoutez ceci au pom.xml:

...

<repositories>
   <repository>
       <id>lib_id</id>
       <url>file://${project.basedir}/lib</url>
   </repository>
</repositories>

...

<dependencies>
  ...
  <dependency>
      <groupId>com.mylibrary</groupId>
      <artifactId>mylibraryname</artifactId>
      <version>1.0.0</version>
  </dependency>
  ...
</dependencies>
Fulgencio Jara
la source
4

nous sommes passés à gradle et cela fonctionne beaucoup mieux à gradle;). nous spécifions simplement un dossier dans lequel nous pouvons déposer des pots pour des situations temporaires comme celle-ci. Nous avons encore la plupart de nos pots définis dans la section de gestion des dépendances typiques (c'est-à-dire les mêmes que maven). C'est juste une dépendance de plus que nous définissons.

Donc, fondamentalement, maintenant, nous pouvons simplement déposer n'importe quel pot que nous voulons dans notre répertoire lib pour un test temporaire s'il n'est pas quelque part dans un référentiel in maven.

Dean Hiller
la source
1
Pourriez-vous donner un exemple de la façon dont vous avez procédé?
Thomas
2

Un petit ajout à la solution proposée par Pascal

Lorsque j'ai suivi cette route, j'ai eu une erreur dans maven lors de l'installation du pot ojdbc.

[INFO] --- maven-install-plugin:2.5.1:install-file (default-cli) @ validator ---
[INFO] pom.xml not found in ojdbc14.jar

Après avoir ajouté -DpomFile, le problème a été résolu.

$ mvn install:install-file -Dfile=./lib/ojdbc14.jar -DgroupId=ojdbc \
   -DartifactId=ojdbc -Dversion=14 -Dpackaging=jar -DlocalRepositoryPath=./repo \
   -DpomFile=~/.m2/repository/ojdbc/ojdbc/14/ojdbc-14.pom
veeseekay
la source
0

Vous pouvez utiliser eclipse pour générer un fichier exécutable: fichier d'exportation / fichier exécutable

user1942990
la source
Je ne sais pas si cela répond à la question. Il a déjà le dossier en pot.
Johannes Jander
Eclipse prend en charge les uberjar ou les pots ombragés, c'est donc une solution, mais pas pour maven
Alex Lehmann