2014-10-28 14 views
11

A causa di alcune incompatibilità tra due dipendenze, sono stato costretto a fare una versione all'ombra di una delle mie dipendenze. Ciò significa che il mio progetto ora dipende da un file .jar locale.Installare la dipendenza vaso locale come parte del ciclo di vita, prima di Maven tenta di risolverlo

ero in precedenza perfettamente bene con solo utilizzando mvn install-file installare questo .jar al mio deposito locale, prima di eseguire mvn install:

mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=lib/my-custom-jar-1.0.0.jar 
mvn install 

Tuttavia, il mio progetto sarà ora su un server di compilazione automatica, che solo la volontà fare mvn clean install e nient'altro.

Cercando a lungo, ho trovato diverse soluzioni, ma nessuna è perfetta.

sarò scrivere le soluzioni che ho trovato come una risposta al di sotto, ma sto postando questa domanda sperando che qualcuno ha un'idea migliore per risolvere questo problema.

+0

La versione ombreggiata creata da maven-shade-plugin o build da una build di maven? – khmarbaise

+0

Entrambi credo. È costruito da una build di maven che ha il plug-in maven-shade come parte del suo ciclo di vita. Questa era la soluzione a un problema che avevo con i conflitti di dipendenza. [Vedi questa domanda precedente che ho fatto.] (Http://stackoverflow.com/questions/24066027/spring-core-dependency-version-error-with-a-jenkins-plugin) – Wiwiweb

+0

Possibile duplicato di [Posso aggiungere giare a maven 2 crea classpath senza installarli?] (http://stackoverflow.com/questions/364114/can-i-add-jars-to-maven-2-build-classpath-without-installing-them) – Stephan

risposta

27

Ecco le poche soluzioni che ho provato, ma non sono stati grandi per i miei usi:

1. Maven-install-plugin

L'idea è quella di aggiungere l'obiettivo install-file come parte dell'installazione ciclo di vita con l'aggiunta di questo al pom:

<plugin> 
    <artifactId>maven-install-plugin</artifactId> 
    <version>2.5.2</version> 
    <executions> 
    <execution> 
     <phase>validate</phase> 
     <goals> 
     <goal>install-file</goal> 
     </goals> 
     <configuration> 
     <file>lib/my-custom-jar-1.0.0.jar</file> 
     </configuration> 
    </execution> 
    </executions> 
</plugin> 

[...] 

<dependency> 
    <groupId>org.me</groupId> 
    <artifactId>my-custom-jar</artifactId> 
    <version>1.0.0</version> 
</dependency> 

Tuttavia, anche il primo obiettivo, validate, Maven cercherà di risolvere le dipendenze prima di installare file viene eseguito.

Ho visto l'idea di usare l'obiettivo pulito. Fastidiosamente, questo funziona quando si eseguono comandi separati (mvn clean && mvn install) ma se si eseguono entrambi in un comando mvn (mvn clean install), Maven risolverà prima le dipendenze. Potrebbe esserci una soluzione a questo?

2. Multi Modulo Progetto

L'idea, seen in this Stack Overflow answer, è che si installa-file nel POM genitore, e aggiungere la dipendenza nel pom bambino. Maven risolverà solo le dipendenze separatamente, quindi dovrebbe funzionare.

Tuttavia il mio progetto è un singolo modulo, e facendo un genitore falso solo per risolvere questo problema sembra un eccesso di complicazione e un brutto hack. portata

3. Sistema con basedir

<dependency> 
    <groupId>org.me</groupId> 
    <artifactId>my-custom-jar</artifactId> 
    <version>1.0.0</version> 
    <scope>system</scope> 
    <systemPath>${basedir}/lib/my-custom-jar-1.0.0.jar</systemPath> 
</dependency> 

Anche se questo si presenta così è stato fatto proprio per questo tipo di situazione, il campo di applicazione del sistema in realtà si aspetta che la dipendenza di essere su tutti i sistemi in cui si esegue il progetto e quindi non sarà impacchettato nel file .war, rendendo il mio progetto non funzionale.

4. addjars-maven-plugin

This custom plugin found here include un .jar nel file .war, poi aggiunge al vostro pom durante la compilazione.

<plugin> 
    <groupId>com.googlecode.addjars-maven-plugin</groupId> 
    <artifactId>addjars-maven-plugin</artifactId> 
    <version>1.0.5</version> 
    <executions> 
    <execution> 
     <goals> 
     <goal>add-jars</goal> 
     </goals> 
     <configuration> 
     <resources> 
      <resource> 
      <directory>${basedir}/lib</directory> 
      <includes> 
       <include>**/my-custom-jar-1.0.0.jar</include> 
      </includes> 
      </resource> 
     </resources> 
     </configuration> 
    </execution> 
    </executions> 
</plugin> 

Questo funzionerà nei casi più normali. Tuttavia, dal momento che non indichi alcuna dipendenza dal tuo custom .jar nel tuo attuale pom, l'IDE mancherà di molte classi, quindi dovrai aggiungere manualmente il tuo .jar personalizzato come una libreria esterna.

Questo è ancora un po 'hacky e non funziona con alcuni casi particolari (hpi: run per il debugging di Jenkins ad esempio genera alcuni errori). Inoltre ho preferito che il mio codice non si basasse su plug-in di terze parti.

5. In-directory repository Maven

ho trovato questa soluzione dopo la creazione di questo post, e sono abbastanza soddisfatto.

Questo è praticamente lo stesso risultato del comando mvn install-file nella mia domanda, tranne che si salva il risultato e lo si mantiene come parte del progetto installando la libreria personalizzata in un repository situato all'interno del progetto.

Sarà necessario preinstallare la libreria utilizzando questo comando.

mvn org.apache.maven.plugins:maven-install-plugin:2.5.1:install-file \ 
-Dfile=lib/cloudfoundry-client-lib-shaded-1.0.3.jar \ 
-DlocalRepositoryPath=lib 

Una volta fatto il repository viene creato nella cartella lib e non avrà bisogno di fare questo comando mai più.

indicare che si desidera utilizzare questo repository nel pom:

<repository> 
    <id>Local repository</id> 
    <url>file://${basedir}/lib</url> 
</repository> 

[...] 

<dependency> 
    <groupId>org.me</groupId> 
    <artifactId>my-custom-jar</artifactId> 
    <version>1.0.0</version> 
</dependency> 

Questa soluzione ti costringe a commettere una serie di cartelle supplementare al vostro SCM, ma che è stato un inconveniente gestibile per me e io sono soddisfatto di questo.

+0

Buona risposta. Al n. 4, come è "necessario aggiungere manualmente il file .jar personalizzato come libreria esterna"? – Gobliins

+0

Questo serve solo per assicurarsi che l'IDE funzioni correttamente. Dove impostare questo dipenderà dal tuo IDE. – Wiwiweb

+3

Tre anni e niente di meglio? Non abbiamo ancora un modo per farlo! – markthegrea

1

Esegue l'ombreggiatura in un sottoprogetto (chiamatelo S), mangia la versione (a) della dipendenza del problema e produce il proprio risultato G/A/V'd. Configura ombra per produrre l'output principale del sottoprogetto. In altre parole, S produce gruppo: artefatto: versione che sono completamente diverse dalle coordinate della cosa da cui si parte, di cui si ha bisogno di due versioni di.

Negli altri sottoprogetti, dichiarare semplicemente (S) come dipendenza per ottenere la versione ombreggiata e quindi è possibile dichiarare l'altra versione non ombreggiata.

Questo è tutto presupponendo di aver rinominato i pacchetti quando si è ombreggiato.

Non c'è bisogno di installazione: niente.

+0

Non sono sicuro di capire cosa stai dicendo. Le mie due dipendenze sono org.cloudfoundry: cloudfoundry-client-lib e org.jenkins-ci.plugins: plugin. Entrambi dipendono da diverse versioni del nucleo della molla. Ho creato "cloudfoundry-client-lib-shaded.jar" che ha ribattezzato spring-core, e ora ho bisogno di averlo installato. – Wiwiweb

+0

Non è necessario averlo installato. Devi solo averlo aggiunto al reattore tramite il plugin ombra. shadedArtifactAttached true lo farà. – bmargulies

Problemi correlati