Differenza tra compilazione dell'ambito maven e confezione JAR


260

Qual è la differenza tra l'ambito maven compilee providedquando l'artefatto è costruito come JAR? Se fosse una GUERRA, capirei che il manufatto sarebbe incluso o meno in WEB-INF / lib. Ma nel caso di un JAR non importa - le dipendenze non sono incluse. Devono essere sul percorso di classe quando il loro ambito è compileo provided. So che le provideddipendenze non sono transitive, ma è solo una differenza?

Risposte:


289

Dal documento Maven :

  • compilare

    Questo è l'ambito predefinito, usato se non ne viene specificato nessuno. Le dipendenze di compilazione sono disponibili in tutti i percorsi di classe di un progetto. Inoltre, tali dipendenze vengono propagate a progetti dipendenti.

  • fornito

    È molto simile alla compilazione, ma indica che ci si aspetta che JDK o un contenitore forniscano la dipendenza in fase di esecuzione. Ad esempio, quando si crea un'applicazione Web per Java Enterprise Edition, è necessario impostare la dipendenza dall'API Servlet e dalle relative API Java EE sull'ambito fornito poiché il contenitore Web fornisce tali classi. Questo ambito è disponibile solo sul percorso di classe di compilazione e test e non è transitivo.

Ricapitolare:

  • le dipendenze non sono transitive (come hai detto)
  • l'ambito fornito è disponibile solo sul percorso di classe di compilazione e test, mentre l'ambito di compilazione è disponibile in tutti i percorsi di classe.
  • le dipendenze fornite non vengono impacchettate

5
Si, lo so. Ma rifletto sulla differenza degli ambiti nel JAR packagingcontesto. Maven doc non ne parla. Uso Maven da un po ', ma mi sono già chiesto a questo proposito :) Quindi nel JAR packagingcontesto non sembra esserci alcuna differenza tra compilee provided(tranne la transizione di dipendenza). Ho ragione?
emstol,

3
@Jacob cosa si intende per "considerando che l'ambito della compilazione è disponibile in tutti i percorsi di classe ."?
Geek

1
Penso che "NOT Transitive" sia il grosso problema qui. Perché l'inferno delle dipendenze è qualcosa che gli sviluppatori affrontano molto frequentemente e l'ambito fornito gli impedisce di andare avanti e fare casino con altre versioni è fondamentale.
Seetharamani Tmr

2
Penso che la differenza sia nella fase di confezionamento. Con la compilazione, includerà il vaso nella guerra finale o il vaso (come il vaso eseguibile dello stivale a molla), e fornito potrebbe non esserlo. Poiché il jar fornito può essere fornito dal contenitore Web (come put nella cartella ext lib), non è nel pacchetto di guerra se non dipendente da altri ambiti, compilazione, runtime.
Addo Zhang,

1
@emstol Tornando alla tua domanda originale, hai ragione nel caso in cui JAR le dipendenze non siano impacchettate all'interno del JAR stesso. Ma in Mven, un packaging JAR significa che vuoi che sia usato come libreria. Non appena lo si importa in qualche altro progetto maven, le dipendenze transitive saranno portate se lo scopo è compilee non lo sarà se lo è provided.
LeoLuz,

291

Compilare significa che è necessario il JAR per compilare ed eseguire l'app. Per un'applicazione Web, ad esempio, il JAR verrà inserito nella directory WEB-INF / lib.

Fornito significa che è necessario il JAR per la compilazione, ma in fase di esecuzione esiste già un JAR fornito dall'ambiente, quindi non è necessario che sia impacchettato con l'app. Per un'app Web, ciò significa che il file JAR non verrà inserito nella directory WEB-INF / lib.

Per un'app Web, se il server delle app fornisce già il JAR (o la sua funzionalità), usa "fornito", altrimenti usa "compila".

Ecco il riferimento.


11
Non stai rispondendo alla domanda del PO? ' Che differenza c'è nell'usare la compilazione dell'ambito maven e fornita quando l'artefatto è costruito come JAR ? 'Si noti che l'autore afferma esplicitamente di conoscere la differenza quando si confeziona come una guerra.
Alberto,

posso utilizzare fornito se sto facendo riferimento a un altro JAR distribuito sullo stesso server delle applicazioni ??
Samy Omar,

1
Per essere chiari, una dipendenza fornita non viene aggiunta al percorso di classe quando mvn exec:javaviene eseguita, ma una dipendenza compilata lo è.
Jamie,

Ho posto questa domanda - stackoverflow.com/questions/37360132/… Il problema è stato risolto cambiando l'ambito da fornito a compilato. Ma non vedo alcuna differenza tra jar compilato con ambito "fornito" e jar compilato con ambito "compilazione". Potresti spiegare perché?
Pavel_K,


22

Se stai pianificando di generare un singolo file JAR con tutte le sue dipendenze (il tipico xxxx-all.jar), allora l'ambito fornito è importante, perché le classi all'interno di questo ambito non saranno pacchetto nel JAR risultante.

Vedi maven-assembly-plugin per maggiori informazioni


7
a condizione che la dipendenza ==> la dipendenza NON sia impacchettata.
Gab 是 好人

3
La confusione di OP viene chiaramente risolta quando si effettua il pacchetto maven-assembly-plugin, interessante il fatto che le risposte più votate non lo menzionino.
Henrique G. Abreu,

Non capisco questa risposta. Sembra più un commento.
reinierpost,

11
  • compilare

Rendi disponibile nel percorso di classe, non aggiungere questa dipendenza nel vaso finale se è un vaso normale; ma aggiungi questo vaso nel vaso se il vaso finale è un vaso singolo (ad esempio, vaso eseguibile)

  • fornito

La dipendenza sarà disponibile nell'ambiente di runtime, quindi non aggiungere questa dipendenza in ogni caso; anche non in un singolo vaso (es. vaso eseguibile ecc.)


3

Per un file jar, la differenza è nel percorso di classe elencato nel file MANIFEST.MF incluso nel jar se addClassPath è impostato su true nella configurazione del plugin maven-jar. le dipendenze 'compilare' appariranno nel manifest, le dipendenze 'fornite' no.

Uno dei miei animali domestici è che queste due parole dovrebbero avere lo stesso tempo. O compilato e fornito, oppure compilare e fornire.


0

Quando si imposta maven scope come provided, significa che quando viene eseguito il plug-in, la versione delle dipendenze effettivamente utilizzata dipenderà dalla versione di Apache Maven installata.


0

Se il file jar è simile al file jar di avvio a molla eseguibile, l'ambito di tutte le dipendenze deve essere compilequello di includere tutti i file jar.

Ma se il file jar viene utilizzato in altri pacchetti o applicazioni, non è necessario includere tutte le dipendenze nel file jar poiché questi pacchetti o applicazioni possono fornire autonomamente altre dipendenze.

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.