Dividere un grande progetto per creare un progetto Maven multi-modulo


23

Sto lavorando a un'applicazione Spring-MVC in cui stiamo usando Maven per la gestione delle dipendenze. Poiché il progetto è grande, stiamo pensando di dividere il progetto in più parti. Ho avuto qualche dubbio, che spero di ottenere risposte qui.

Attualmente, stiamo implementando un singolo file WAR come ROOT.warsu Apache tomcat sul nostro server. Poiché il progetto è grande, ci sono parti nella webapp come Notifiche ed e-mail, Servizi di terze parti, PUSH (Cometd), API REST, ecc. Attualmente tutti sono clubbati e dipendono l'uno dall'altro. Ad esempio, l' Notificationoggetto dipende anche Persondall'oggetto, poiché le notifiche sono personalizzate per gli utenti.

L'intenzione principale di dividere il grande progetto è quella di essere in grado di lavorare su singoli moduli, per correggere errori, aggiungere funzionalità, test, ecc. E se soddisfatto, solo questo modulo può essere sostituito sul server anziché sull'intera applicazione. È possibile?

Come ho già detto prima, ci sono dipendenze e mappature tra oggetti. Come saranno gestiti attraverso diversi sottomoduli o cambieranno solo le dichiarazioni di importazione per includere altri progetti?

Come ho detto, l'intenzione è quella di lavorare su singoli moduli ed essere in grado di distribuirli (preferibilmente a caldo). Attualmente, abbiamo un solo file WAR come ROOT.war. La divisione creerà più file di guerra, che vengono quindi indicati dall'URL come domain-name.com/module_name/some_mapping?

Attualmente sto controllando la documentazione, ma questo è l'obiettivo principale che vogliamo raggiungere con il multi modulo fornito da Maven e interessato a sapere se questo è fattibile. Se sono necessarie ulteriori informazioni, per favore fatemelo sapere.

Attualmente sto usando un genitore POM dalla primavera come segue:

<parent>
    <groupId>io.spring.platform</groupId>
    <artifactId>platform-bom</artifactId>
    <version>1.1.3.RELEASE</version>
    <relativePath />
</parent>

1
Lascio ad altri la risposta. L'idea è molto valida. Potresti iniziare con un POM padre con dependencyManagement e un barattolo per i DAO come Person. Una biblioteca molto semplice. E così via. Ovviamente nessuna dipendenza ciclica.
Joop Eggen,

Risposte:


20

È possibile ?

Sì certamente. In passato ho strutturato alcuni progetti come questo, qui alcuni bit che spero possano iniziare.

Ci sono due caratteristiche principali di Maven che userete per intrecciare le cose:

Dividere e conquistare

Dovrai dividere i tuoi progetti in più progetti indipendenti. Qui per indipendente intendo che tutti i riferimenti al codice al di fuori del progetto sono fatti attraverso dipendenze in Maven e non unendo direttamente l'albero dei sorgenti.

A seconda dello stato dell'albero di origine, ciò potrebbe rappresentare molto lavoro. Detto questo, non stai facendo lo calzascarpe a Maven, ma piuttosto un mezzo per strutturare e disinfettare la tua base di codice. Pensalo come il tuo punto di partenza, molto più facile da trovare qui:

Simpatico ripostiglio

di qui:

Spogliatoio non così bello

Maven fa molto affidamento sulla convenzione quindi meglio è organizzata la tua roba, più Maven può aiutarti. Detto questo, potrebbe essere necessario riorganizzarsi per adattarsi meglio alla propria convenzione e se devo dare un consiglio qui è che è MOLTO più facile cambiare le tue cose per adattarle alle convenzioni di Maven che cercare di configurare Maven per capire la tua convenzione.

Se questi progetti potessero essere utilizzabili al di fuori dell'applicazione principale, potrebbero vivere come librerie veramente indipendenti e incluse anche se dipendenze di Mven. Dovrebbero vivere nel proprio repository (non nell'albero dei sorgenti dell'applicazione) e non dovrebbero dipendere da nessuna parte dell'applicazione principale.

Parti principali dell'applicazione, una volta suddivise in progetti, possono essere unite come moduli. In genere li avrai collocati come sottocartella della cartella di origine principale della tua app.

Anche il POM principale per la tua app conterrà la dichiarazione del modulo. Inserirai anche tutte le dipendenze comuni per la tua app, oltre a dichiarare la maggior parte dei plug-in di build e la loro configurazione. Anche qui ti consiglio vivamente di inserire un gruppo di proprietà per cose come la versione dell'applicazione che puoi riutilizzare nei moduli. Molto più facile da gestire quando tutto ha la stessa versione e avere la versione in un unico posto fa funzionare tutto questo.

Tooling

Se sei un team più grande di 1, ti consiglio vivamente di installare un repository per le tue dipendenze Maven. Guarda Artifactory , Nexus o Archiva . Puoi configurare il file POM per installarlo direttamente su questi, quindi una volta eseguito non dovrebbe essere un gran sovraccarico, ma risparmierai molto tempo al tuo team risolvendo le dipendenze con il jar corretto nel posto giusto.

Per quanto riguarda gli utensili, il prossimo passo logico è un sistema di integrazione continua ( Jenkins , ce ne sono molti altri). Gestirà la costruzione del sorgente eseguendo i test e spingendo verso l'artefatto, con tutto questo in atto tutto ciò che devi fare è lavorare il codice e il resto funziona.

Dal momento che stai impacchettando la tua app come un mago della guerra in grado di gestire la costruzione della guerra e posizionare tutte le dipendenze nei rispettivi luoghi senza dover unire file jar o altri lavori simili in giro, quindi non preoccuparti.

Esempio

Potrei andare avanti molto più a lungo qui, ma niente è meglio di un buon esempio. Cerca su github progetti di grandezza simile e guarda come hanno creato i loro file pom e le gerarchie di cartelle. Guarda più di uno, alcuni si adatteranno meglio alla tua configurazione di altri, nessuno incarnerà davvero la verità ma dovresti trovare abbastanza per alimentare i tuoi pensieri su come farlo.

Prendi Jenkins per esempio:

Puoi vedere che il loro genitore POM è piuttosto esteso.

Usano i moduli come puoi vedere in questa sezione:

<modules>
    <module>core</module>
    <module>war</module>
    <module>test</module>
    <module>cli</module>
</modules>

E ogni modulo corrisponde a una sottocartella con lo stesso nome che contiene anche un POM. Puoi nidificare quanti ne vuoi in questo modo, anche se mantienilo entro livelli di sanità mentale;).

Inizia in piccolo

Se non hai mai usato Maven, ti suggerisco di non iniziare subito con i moduli. Vacci piano, inizia con, dì una delle librerie più semplici che potresti avere e trasformalo in un progetto maven. Quindi trasforma la tua applicazione principale in un semplice progetto maven. Una volta che funziona, inizia ad aggiungere semplici dipendenze, quindi dividi il tuo primo modulo e così via.

Maven è un ottimo strumento, ma può anche essere un super dolore al collo, specialmente quando le cose non vanno per il verso giusto. A partire da tutto il whammy al primo tentativo è un destinatario del disastro (era per me!).

Se le cose sono un po 'strane puoi sempre usare il mvn help:effective-pomcomando per vedere cosa Maven ha effettivamente capito.

plugins

Dal tuo commento capisco meglio cosa vuoi ottenere. In questo caso, sceglierei l'approccio per plugin. Creare un progetto che esponga l'API dei punti di estensione in cui si desidera isolare il lavoro. Quindi puoi usarlo come dipendenza in un nuovo progetto che lo implementerà. Nella tua applicazione principale basta aggiungere le dipendenze appropriate per queste implementazioni (non usando i moduli maven questa volta) e dovresti essere pronto. Alla fine il progetto principale dell'applicazione non porterà quasi nessun codice sorgente, tutto ciò che viene fatto in progetti esterni e caricato attraverso dipendenze.

Dovrai tuttavia ridistribuire l'intera applicazione con questo approccio, indipendentemente dal fatto che il nucleo sia cambiato o meno poiché la guerra è staticamente costruita dalle dipendenze, cambiare una di esse implica ricostruire il tutto. Sembra peggio di quello che è in realtà, in effetti solo le nuove modifiche verranno effettivamente costruite, il resto sarà sostanzialmente una copia dei precedenti jar. Ma poiché tutto è nel file di guerra, dovrà essere ricostruito e il server dovrà essere arrestato e riavviato.

Se hai bisogno di andare oltre, le cose diventano un po 'più complicate, anche se non impossibili. Consiglierei di esaminare OSGI, Apache Felix potrebbe iniziare, anche se ci sono anche altre implementazioni. Questo ti permetterà di prendere il barattolo esterno e trasformarlo in plugin adeguati. Otterrai un controllo molto maggiore sul ciclo di vita di runtime dei componenti aprendo la porta a ricariche e aggiornamenti dinamici. Richiederà tuttavia importanti modifiche al core così di nuovo, probabilmente non un buon punto di partenza. Tuttavia, una volta che hai un progetto che è ben separato e che tutte le parti sono isolate nel modo che desideri, questo potrebbe essere un passaggio successivo naturale se l'avvio e l'arresto dell'applicazione durante l'aggiornamento è un grosso problema.

La differenza di base tra moduli e dipendenze è questa:

  • I moduli vivranno nello stesso albero dei sorgenti dell'applicazione principale, idealmente come sottocartelle.
  • Le dipendenze possono essere ovunque.

Puoi trovare la Bibbia qui .

Spero che questo aiuti, buona fortuna.


Il raggruppamento dei moduli attraverso Maven anziché l'albero dei sorgenti ha chiarito molte domande che avevo. Potete per favore parlarmi del dispiegamento di un tale progetto. Uno degli altri motivi che stiamo prendendo in considerazione è che gli sviluppatori possano lavorare sul modulo richiesto e apportare le modifiche in tempo reale. Una cosa che desideriamo evitare è arrestare il server delle applicazioni e ricominciare, tranne che per il modulo principale. Come 2 moduli a cui riesco a pensare conterrà codice che cambia spesso. Usiamo tomcat come server delle applicazioni, bilanciato dal carico di Apache. Grazie.
Siamo a Borg il

I moduli Maven si trovano spesso nello stesso albero dei sorgenti dell'applicazione principale. L'uso di moduli Maven all'esterno dell'albero dei sorgenti è in realtà più complicato di quanto valga davvero la pena. Se si ospitano progetti all'esterno dell'albero di origine, selezionare progetti indipendenti normali e utilizzare dipendenze normali.
Newtopian,

Penso che andremo ad aggiungere parti del nostro progetto direttamente come dipendenze di Maven. In questo modo, possiamo lavorare direttamente su parti del progetto. Solo una domanda che avevo, se aggiungiamo uno dei sottoprogetti come dipendenza in POM.xml, diciamo versione 2.0.0, e quindi con alcune modifiche, spingiamo un 2.0.1 del modulo su sonatype, come possiamo dire direttamente al modulo principale di andare per 2.0.1, sarà sufficiente cambiare POM.xml all'interno di ROOT.war ed eliminare la directory ROOT. L'intenzione principale è di non arrestare il server. Grazie.
Siamo a Borg il

pom.xml non ha alcuna rilevanza una volta che la guerra è stata creata, ovvero Tomcat (o qualunque contenitore tu usi) non usa questo file. Il file viene utilizzato da Maven per creare un nuovo file di guerra, che a sua volta dovrai distribuire sul server. Quindi il ciclo funziona sul codice, crea un file jar, aggiorna la versione in POM di guerra, crea un file di guerra, aggiorna il server con il nuovo file di guerra. Alcuni server supporteranno la re-distribuzione a caldo, sebbene in genere ciò implicherebbe la disattivazione dell'applicazione per alcuni secondi.
Newtopian,
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.