2009-05-28 10 views
19

Stiamo usando Maven 2.1.0. Ho più moduli che sono completamente separati, ma hanno ancora molte dipendenze comuni. Come log4J, ma alcuni moduli non ne hanno bisogno. Mi chiedo se sia una buona idea dichiarare tutte le dipendenze comuni in un file principale nella sezione <dependencyManagement> o c'è un modo migliore per gestire questo?Dichiarare dipendenza nella sezione <dependencyManagement> anche se la dipendenza non è utilizzata ovunque?

Una domanda di follow-up su <dependencyManagement>. Se dichiaro Log4J nella sezione <dependencyManagement> del genitore e un sottoprogetto non lo usa, sarà comunque incluso?

+0

Fail @Kieveli per inutile risposta non utile. – Jherico

+0

Penso che le dipendenze condivise/comuni debbano essere sicuramente configurate nella sezione dependencyManagement. La domanda è, se una volta che vai su questo percorso non dovresti aggiungere tutte le dipendenze (condivise o meno) in dependencyManagement. Posso vedere pro e contro per entrambi. Qualche buona pratica per questo? – Hardy

risposta

8

Ogni modulo deve avere il proprio POM e dove dichiara le proprie dipendenze. Questo non solo traccia le dipendenze esterne, ma anche quelle interne.

Quando si utilizza Maven per creare un progetto, verrà risolto l'intero lotto. Quindi se molti moduli (forse tutti) dipendono da log4j, saranno inclusi solo una volta. Ci sono alcuni problemi se i tuoi moduli dipendono da diverse versioni di log4j ma questo approccio di solito funziona bene.

È anche utile (se ci sono più di 1-2 sviluppatori che lavorano insieme) per configurare un repository interno (come Artifactory) e utilizzarlo internamente. Rende molto più facile gestire le librerie che non sono nei repository pubblici (basta aggiungerle al repository interno!) E puoi anche usare gli strumenti di compilazione per spingere build del tuo codice lì in modo che altri possano usare i moduli senza fare il check-out il codice (utile nei progetti più grandi)

0

In un progetto multi-modulo, inserisco qualsiasi dipendenza comune nell'elemento del padre pom.xml. Non sono sicuro che sarebbe una buona pratica se i moduli non fossero collegati allo stesso progetto.

1

Una domanda di follow-up su. Se dichiaro Log4J nella sezione del genitore e un sottoprogetto non lo usa, sarà comunque incluso?

No. La gestione delle dipendenze imposta solo la versione di default e, eventualmente, la portata (Ho visto questo entrambi sembrano essere ereditata e sembrano non essere ereditata così hai bisogno di guardare questo uno da soli). Per includere la dipendenza in un modulo figlio, devi dichiararlo come dipendenza del modulo ed omettere l'elemento versione. È possibile sovrascrivere il valore predefinito in un modulo figlio includendo semplicemente il numero di versione nell'elemento dipendenza del POM del modulo figlio.

I moduli multipli sono completamente separati, ma hanno ancora molte dipendenze comuni.

In questo caso, sì e no.

Per i moduli che sono costruiti, versionati e distribuiti insieme come un progetto unificato, ad esempio i moduli che compongono una singola applicazione Web, sicuramente sì. Volete liberarvi dal mal di testa di modificare la versione in più di un POM quando decidete di passare a una nuova versione di una dipendenza. Può anche risparmiare lavoro quando è necessario escludere determinate dipendenze transitive. Se dichiari la dipendenza con le sue esclusioni nella sezione, non devi mantenere le esclusioni in più POM.

Per i moduli che non sono direttamente collegate, ma sono costruiti all'interno di un unico team all'interno dell'azienda che si può prendere in considerazione dichiarando versioni predefinite per le biblioteche comuni, come il test utilities, la registrazione utilities, ecc al fine di mantenere la squadra a lavorare con il versioni standard degli strumenti che hai definito come parte delle tue migliori pratiche.Ricorda che puoi sempre aumentare la versione del tuo Super POM quando ti standardizzi su un nuovo set di librerie comuni. Dove tracciare la linea tra la libreria e gli strumenti standardizzati e le librerie e gli strumenti specifici del progetto dipende da te, ma dovrebbe essere facile da trovare per il tuo team.

31

Se si dispone di un progetto padre, è possibile dichiarare tutte le dipendenze e le relative versioni nella sezione dependencyManagement del padre padre. Questo non significa che tutti i progetti useranno tutte quelle dipendenze, vuol dire che se un progetto non dichiarare la dipendenza, che erediterà la configurazione, in modo che solo bisogno di dichiarare il groupId e artifactId della dipendenza. Puoi anche dichiarare i tuoi progetti figli nel dependencyManagement del genitore senza introdurre un ciclo.

Nota si può anche fare simile con i plugin di dichiarandoli nella sezione pluginManagement. Questo significa che ogni bambino dichiara che il plugin erediterà la configurazione.

Ad esempio, se si dispone di 4 progetti, genitore, nucleo, ui e utils, si potrebbe dichiarare tutte le dipendenze esterne e le versioni di progetto interne del genitore. I progetti figli ereditano quindi quella configurazione per tutte le dipendenze dichiarate. Se tutti i moduli devono avere la stessa versione, questi possono essere addirittura dichiarati come proprietà nel genitore.

Un genitore esempio è il seguente:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>name.seller.rich</groupId> 
    <artifactId>parent</artifactId> 
    <version>1.0.0</version> 
    <packaging>pom</packaging> 
    <dependencyManagement> 
    <dependencies> 
     <dependency> 
     <groupId>commons-io</groupId> 
     <artifactId>commons-io</artifactId> 
     <version>1.4</version> 
     </dependency> 
     <dependency> 
     <groupId>name.seller.rich</groupId> 
     <artifactId>ui</artifactId> 
     <version>${project.version}</version> 
     </dependency> 
     <dependency> 
     <groupId>name.seller.rich</groupId> 
     <artifactId>core</artifactId> 
     <version>${project.version}</version> 
     </dependency> 
     <dependency> 
     <groupId>name.seller.rich</groupId> 
     <artifactId>utils</artifactId> 
     <version>${project.version}</version> 
     </dependency> 
    </dependencies> 
    </dependencyManagement> 
    <modules> 
    <module>utils</module> 
    <module>core</module> 
    <module>ui</module> 
    </modules> 
</project> 

E i utils, Core e progetti ui ereditano tutte le versioni interessate. utils:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>name.seller.rich</groupId> 
    <artifactId>utils</artifactId> 
    <!--note version not declared as it is inherited--> 
    <parent> 
    <artifactId>parent</artifactId> 
    <groupId>name.seller.rich</groupId> 
    <version>1.0.0</version> 
    </parent> 
    <dependencies> 
    <dependency> 
     <groupId>commons-io</groupId> 
     <artifactId>commons-io</artifactId> 
    </dependency> 
    </dependencies> 
</project> 

fondamentali:

<project> 
<modelVersion>4.0.0</modelVersion> 
<groupId>name.seller.rich</groupId> 
<artifactId>core</artifactId> 
<parent> 
    <artifactId>parent</artifactId> 
    <groupId>name.seller.rich</groupId> 
    <version>1.0.0</version> 
</parent> 
<dependencies> 
    <dependency> 
    <groupId>name.seller.rich</groupId> 
    <artifactId>utils</artifactId> 
    </dependency> 
</dependencies> 

ui:

<project> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>name.seller.rich</groupId> 
    <artifactId>ui</artifactId> 
    <parent> 
    <artifactId>parent</artifactId> 
    <groupId>name.seller.rich</groupId> 
    <version>1.0.0</version> 
    </parent> 
    <dependencies> 
    <dependency> 
     <groupId>name.seller.rich</groupId> 
     <artifactId>core</artifactId> 
    </dependency> 
    </dependencies> 
</project> 
+0

Qualcosa di simile è disponibile per i plugin? Ad esempio, se voglio impostare la versione 'maven-compiler-plugin' su' 3.1' nei progetti, posso farlo in un POM padre? E riguardo la configurazione del compilatore? –

+1

Ah, non importa --- Ho trovato l'elemento 'pluginManagement'; non era elencato nella lista principale delle sezioni su http://maven.apache.org/pom.html e dovevo guardare più in basso. –

1

Usiamo un solo genitore comune con un blocco dependencyManagement per tutti i nostri progetti. Questo sta iniziando a crollare mentre spostiamo più progetti in esperti - se un progetto richiede una versione diversa, dobbiamo dichiararlo come dipendenza per tutti i bambini o definire esplicitamente la versione per ogni bambino pertinente.

Stiamo provando un modello in cui dividiamo dependencyManagement dal nostro genitore comune e quindi importiamo il nostro Pom di gestione delle dipendenze aziendali nel pom del progetto di livello superiore. Questo ci consente di definire selettivamente i valori predefiniti del progetto che sostituiscono i valori predefiniti aziendali.

Ecco lo scenario originale:

A defines version 1.0 of foo.jar as the corporate default 
B child of A 
C1, C2, C3 children of B 
D1, D2, D3 children of C1, C2, C3 respectively 

Se D1 e D2 richiedono la versione 1.1 di foo.jar, quindi la nostra scelta usato per essere:

  1. Declare foo.jar versione 1.1 come dipendenza in B, facendo apparire che C1, C2, C3 e D3 dipendessero anche dalla versione 1.1
  2. Dichiarare foo.jar versione 1.1 come dipendenza in D1 e D2, spostando la dichiarazione di dipendenza in più punti più in profondità nella nostra gerarchia di progetto.

Ecco quello che stiamo provando:

A defines version 1.0 of foo.jar as the corporate default 
B dependencyManagement: imports A, declares a default of foo.jar version 1.1 
C1, C2, C3 children of B 
D1, D2, D3 children of C1, C2, C3 respectively 

Ora D1 e D2 solo dichiarare una dipendenza da foo.jar e pick up versione 1.1 dal blocco dependencyManagement di B.

16

Ho scritto una lista di best practices. Qui ci sono i più importanti.

  • Utilizzare sempre la maven-enforcer-plugin
    • Enforce dependency convergence
      • In caso contrario è possibile che si dipende da due vasetti diversi, che entrambi dipendono log4j. Quello che si usa in fase di compilazione dipende da un insieme di regole che non dovresti ricordare. Possono entrambi (!) Essere esportati come dipendenze transitive.
    • Richiede plugin versions (per tutti i plugin, anche costruito in quelli)
      • definirli in pluginManagement nel POM genitore per definire le versioni
      • caso contrario, una nuova versione di Maven-infallibile-plugin potrebbe rompersi il vostro costruire
  • Usa dependencyManagement nel POM genitore di utilizzare versioni coerente in tutti i moduli
  • 012.
  • Periodicamente gestita mvn dependency:analyze
    • E 'possibile che state ottenendo una dipendenza transitivamente che dipendono direttamente al momento della compilazione. Se è così, è importante aggiungerlo al tuo pom con la versione richiesta. Questo funziona bene con il plugin di enforcer.
    • È possibile che si dichiarino dipendenze aggiuntive che non si utilizzano. Questo non funziona correttamente al 100% delle volte, specialmente con le librerie progettate per avere pezzi opzionali (ad esempio slf4j-api viene rilevato correttamente, ma slf4j-log4j12 fallisce).
Problemi correlati