Maven: aggiungi una dipendenza a un barattolo per percorso relativo


232

Ho un barattolo proprietario che voglio aggiungere al mio pom come dipendenza.

Ma non voglio aggiungerlo a un repository. Il motivo è che voglio che i miei soliti comandi di maven come mvn compile, ecc., Funzionino immediatamente . (Senza chiedere agli sviluppatori di aggiungerlo ad alcuni repository da soli).

Voglio che il jar sia in una libreria di terze parti nel controllo del codice sorgente, e collego ad esso tramite il percorso relativo dal file pom.xml.

Può essere fatto? Come?

Risposte:


343

Voglio che il jar sia in una libreria di terze parti nel controllo del codice sorgente, e collego ad esso tramite il percorso relativo dal file pom.xml.

Se lo vuoi davvero (capisci, se non puoi usare un repository aziendale), allora il mio consiglio sarebbe di usare un "repository di file" locale per il progetto e di non usare una systemdipendenza con ambito. L' systemambito dovrebbe essere evitato, tali dipendenze non funzionano bene in molte situazioni (ad es. Nell'assemblaggio), causano più problemi che benefici.

Quindi, invece, dichiarare un repository locale al progetto:

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

Installa la tua lib di terze parti lì usando install:install-fileil localRepositoryPathparametro:

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

Aggiornamento: sembra che install:install-fileignori l' localRepositoryPathutilizzo della versione 2.2 del plugin. Tuttavia, funziona con la versione 2.3 e successive del plugin. Quindi usa il nome completo del plugin per specificare la versione:

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>

documentazione di maven-install-plugin

Infine, dichiaralo come qualsiasi altra dipendenza (ma senza systemambito):

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

Questa è una soluzione migliore dell'IMHO rispetto all'utilizzo di un systemambito poiché la tua dipendenza sarà trattata come un buon cittadino (ad esempio, sarà inclusa in un'assemblea e così via).

Ora, devo dire che il "modo giusto" per affrontare questa situazione in un ambiente aziendale (forse non è il caso qui) sarebbe quello di utilizzare un repository aziendale.


2
Questa è un'ottima idea, ma su Maven 2.2.1 il plug-in di installazione sembra ignorare localRepositoryPath...
Jake,

1
Perché dichiarare un repository locale? Perché non lasciarlo andare in ~ / .m2 / con il resto.
Leif Gruenwoldt,

6
@ leif81 Perché allora il repository e le librerie vengono controllati nel repository SCM -> Chiunque esegua un checkout di origine ha tutto ciò di cui ha bisogno per creare una copia della libreria / applicazione.
Darth Android

6
Ho avuto lo stesso problema di @lemon, che ho risolto facendo invece basedir/./my-local-repoun singolo ..
Brian,

2
Il packaging deve essere jar, quindi -Dpackaging = jar
Danila Piatov

127

Utilizzando l' systemambito. ${basedir}è la directory del tuo pom.

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

Tuttavia è consigliabile installare il proprio jar nel repository e non impegnarlo in SCM, dopo tutto ciò che Maven tenta di eliminare.


15
Il sistema dell'ambito deve essere evitato ovunque sia possibile. Installare il JAR nel repository è una soluzione migliore ...
Gandalf StormCrow

14
si, se possibile. ha detto esplicitamente che non voleva metterlo nel repository. Ho aggiunto un commento per sottolineare che questa non è una buona pratica. Ma funziona.
Bozho,

groovy, la tua soluzione è la più accettabile finora immagino .. Ho letto male la domanda
formica

Sì, la domanda stessa esclude la risposta migliore. Mettere tutto nel tuo singolo server di controllo del codice sorgente ha poco a che fare con la "costruzione pronta all'uso"; piuttosto, tutto deve solo essere "controllato". Effettua il check-in pom's & settings.xml (puntando al repository interno ) e usa due server per il tuo progetto: (1) controllo del codice sorgente, (2) controllo del manufatto generato. Ha più senso controllare nei barattoli che fare il check nei dll (il mio vecchio corp in realtà faceva i check-in barattoli e lib.a / .so / .dll. Il nostro server p4 è stato così lento in seguito, alcuni hanno usato segretamente hg per giorno lavoro quotidiano. Problema risolto?
michael

un modo per specificare una directory che contiene invece dei barattoli in modo da non dover aggiungere ognuno come fa Gradle?
Dean Hiller,

29

Questo è un altro metodo in aggiunta alla mia precedente risposta su Posso aggiungere vasi a maven 2 build classpath senza installarli?

Ciò supererà il limite quando si utilizzano build multi-modulo, soprattutto se si fa riferimento al JAR scaricato in progetti figlio all'esterno del genitore. Ciò riduce anche il lavoro di installazione creando i file POM e SHA1 come parte della build. Inoltre, consente al file di risiedere ovunque nel progetto senza correggere i nomi o seguire la struttura del repository maven.

Questo utilizza il plug-in maven-install. Perché questo funzioni, è necessario impostare un progetto multi-modulo e disporre di un nuovo progetto che rappresenti la build per installare i file nel repository locale e assicurarsi che uno sia il primo.

Il tuo progetto multi-modulo pom.xml sarebbe simile al seguente:

<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>

Il file repository / pom.xml conterrà quindi le definizioni per caricare i JAR che fanno parte del progetto. Di seguito sono riportati alcuni frammenti del file pom.xml.

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

La confezione di pom impedisce che ciò esegua test o compili o generi file jar. La carne di pom.xml è nella sezione build in cui viene usato il plugin maven-install.

<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>

Per installare più di un file, basta aggiungere più esecuzioni.


Questa è l'unica cosa che ha funzionato per il mio progetto multi-modulo. L'approccio <repository> locale per un motivo sconosciuto non ha funzionato. Quindi grazie!
Lonzak,

10

Questo funziona per me: diciamo che ho questa dipendenza

<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>

Quindi, aggiungere manualmente il percorso di classe per la dipendenza del sistema in questo modo

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

Configurazione completa:

<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>

9

In precedenza ho scritto di un modello per farlo.

È molto simile alla soluzione proposta da Pascal, sebbene trasferisca tutte queste dipendenze in un modulo di repository dedicato in modo da non doverlo ripetere ovunque venga utilizzata la dipendenza se si tratta di una build multi-modulo.


6

Fondamentalmente, aggiungi questo al 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>

4

siamo passati al livello e questo funziona molto meglio in livello;). specifichiamo semplicemente una cartella in cui possiamo rilasciare i vasetti per situazioni temporanee come quella. Abbiamo ancora la maggior parte dei nostri barattoli definiti nella sezione tipica della gestione delle dipendenze (vale a dire lo stesso di Maven). Questa è solo un'altra dipendenza che definiamo.

quindi in pratica ora possiamo semplicemente rilasciare qualsiasi jar che vogliamo nella nostra directory lib per i test temporanei se non è un repository interno.


1
Potresti fare un esempio di come hai fatto?
Thomas,

2

Una piccola aggiunta alla soluzione pubblicata da Pascal

Quando ho seguito questo percorso, ho riscontrato un errore in Maven durante l'installazione del vaso ojdbc.

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

Dopo aver aggiunto -DpomFile, il problema è stato risolto.

$ 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

0

È possibile utilizzare eclipse per generare un file Jar eseguibile: Esporta / File eseguibile


Non sono sicuro che risponda alla domanda. Ha già il file come un barattolo.
Johannes Jander,

Eclipse supporta uberjar o jar ombreggiato, quindi è una soluzione, ma non per Maven
Alex Lehmann
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.