Różnica między kompilacją zakresu maven a pakietem JAR

260

Jaka jest różnica między zasięgiem maven compilea providedbudowaniem artefaktu jako JAR? Gdyby to była WOJNA, zrozumiałbym - artefakt byłby włączony lub nie w WEB-INF / lib. Ale w przypadku JAR nie ma to znaczenia - zależności nie są uwzględniane. Muszą znajdować się w ścieżce klas, gdy ich zakres to compilelub provided. Wiem, że providedzależności nie są przechodnie - ale czy to tylko jedna różnica?

emstol
źródło

Odpowiedzi:

289

Z dokumentu Maven :

  • skompilować

    Jest to zakres domyślny, używany, jeśli nie określono żadnego. Zależności kompilacji są dostępne we wszystkich ścieżkach klas projektu. Ponadto te zależności są propagowane do zależnych projektów.

  • opatrzony

    Jest to bardzo podobne do kompilacji, ale wskazuje, że oczekujesz, że JDK lub kontener zapewni zależność w czasie wykonywania. Na przykład podczas budowania aplikacji WWW dla Java Enterprise Edition należy ustawić zależność od interfejsu API serwletu i powiązanych interfejsów API Java EE w zakresie podanym, ponieważ kontener WWW udostępnia te klasy. Ten zakres jest dostępny tylko w ścieżce klas kompilacji i testów i nie jest przechodni.

Podsumować:

  • zależności nie są przechodnie (jak wspomniałeś)
  • podany zakres jest dostępny tylko w ścieżce klas kompilacji i testowania, natomiast zakres kompilacji jest dostępny we wszystkich ścieżkach klas.
  • pod warunkiem, że zależności nie są pakowane
Jakub
źródło
5
Tak, wiem. Ale zastanawiam się nad różnicą w zakresie w JAR packagingkontekście. Doktor Maven nie wspomina o tym. Używam Maven przez jakiś czas, ale ja właśnie już zadawałem sobie pytanie o to :) Tak więc wydaje się, że w JAR packagingkontekście, nie ma żadnej różnicy między compilei provided(z wyjątkiem przejścia zależności). Czy mam rację?
emstol,
3
@Jacob, co należy rozumieć przez „podczas gdy zakres kompilacji jest dostępny we wszystkich ścieżkach klas ”.
Geek
1
Myślę, że „NOT Transitive” jest tutaj wielkim haczykiem. Ponieważ piekło uzależnienia jest czymś, z czym programiści spotykają się bardzo często, a zapewniony zakres zapobiega temu i bałagan z innymi wersjami ma kluczowe znaczenie.
Seetharamani Tmr
2
Myślę, że różnica polega na fazie pakowania. W przypadku kompilacji obejmie słoik w ostatecznej wojnie lub słoik (taki jak słoik wykonywalny rozruchu na wiosnę), pod warunkiem, że nie przyniesie rezultatów. Ponieważ dostarczony słoik może być dostarczany z kontenera WWW (np. W folderze ext lib), nie znajduje się on w pakiecie wojennym, jeśli nie jest zależny od innych zakresów, kompilacji, środowiska wykonawczego.
Addo Zhang
1
@ emstol Wracając do twojego pierwotnego pytania, masz rację, że w przypadku JAR zależności nie są zawarte w samym JAR. Ale w maven opakowanie JAR oznacza, że ​​chcesz go używać jako biblioteki. Jak tylko zaimportujesz go do innego projektu maven, zależności przechodnie zostaną wprowadzone, jeśli zakres jest compilei nie będzie, jeśli zakres jest provided.
LeoLuz,
291

Kompilacja oznacza, że ​​potrzebujesz pliku JAR do kompilowania i uruchamiania aplikacji. Przykładowo w przypadku aplikacji internetowej plik JAR zostanie umieszczony w katalogu WEB-INF / lib.

Podane oznacza, że ​​potrzebujesz pliku JAR do kompilacji, ale w czasie wykonywania istnieje już plik JAR dostarczony przez środowisko, więc nie potrzebujesz go w pakiecie z aplikacją. W przypadku aplikacji internetowej oznacza to, że plik JAR nie zostanie umieszczony w katalogu WEB-INF / lib.

W przypadku aplikacji internetowej, jeśli serwer aplikacji już udostępnia plik JAR (lub jego funkcjonalność), użyj „pod warunkiem”, w przeciwnym razie użyj „kompilacji”.

Oto odniesienie.

Owen Cao
źródło
11
Nie odpowiadasz na pytanie PO? „ Jaka jest różnica w stosowaniu kompilacji zakresu maven i zapewnieniu, gdy artefakt jest budowany jako plik JAR ? „Zauważ, że autor wyraźnie stwierdza, że ​​zna różnicę, gdy pakuje się jako wojnę.
Alberto,
czy mogę użyć pod warunkiem, że odwołuję się do innego pliku JAR wdrożonego na tym samym serwerze aplikacji?
Samy Omar
1
Żeby było jasne, podana zależność nie jest dodawana do ścieżki klasy, gdy mvn exec:javajest uruchamiana, ale zależność skompilowana jest.
Jamie,
Zadałem to pytanie - stackoverflow.com/questions/37360132/… Problem został rozwiązany przez zmianę zakresu z podanego na kompilowany. Ale nie widzę żadnej różnicy między słoikiem skompilowanym z „podanym” zakresem a słoikiem skompilowanym z „skompilowanym” zakresem. Czy możesz wyjaśnić dlaczego?
Pavel_K,
Przeczytaj pierwszą odpowiedź: coderanch.com/t/502091/tools/difference-maven-compile-scope
NINCOMPOOP
22

Jeśli planujesz wygenerować pojedynczy plik JAR ze wszystkimi jego zależnościami (typowy xxxx-all.jar), wówczas podany zakres ma znaczenie, ponieważ klasy w tym zakresie nie zostaną umieszczone w wynikowym pliku JAR.

Aby uzyskać więcej informacji, zobacz maven-assembly-plugin

jfcorugedo
źródło
7
pod warunkiem zależności ==> zależność NIE zostanie spakowana.
Gab 是 好人
3
Zamieszanie OP jest wyraźnie rozwiązane, gdy się do niego pakujesz maven-assembly-plugin, ciekawe, że w najczęściej głosowanych odpowiedziach nie ma o tym mowy.
Henrique G. Abreu
Nie rozumiem tej odpowiedzi. Wygląda bardziej jak komentarz.
reinierpost
11
  • skompilować

Udostępnij w ścieżce klasy, nie dodawaj tej zależności do końcowego jar, jeśli jest to normalny jar; ale dodaj ten słoik do słoika, jeśli słoik końcowy jest pojedynczym słoikiem (na przykład słoik wykonywalny)

  • opatrzony

Zależność będzie dostępna w środowisku wykonawczym, więc w żadnym wypadku nie dodawaj tej zależności; nawet nie w jednym słoiku (tj. słoik wykonywalny itp.)

Vijay
źródło
3

W przypadku pliku jar różnica występuje w ścieżce klasy wymienionej w pliku MANIFEST.MF zawartym w pliku jar, jeśli parametr addClassPath ma wartość true w konfiguracji wtyczki maven-jar-plugin. W pliku manifestu pojawią się zależności „kompiluj”, a zależności „pod warunkiem” nie.

Jednym z moich podejrzeń jest to, że te dwa słowa powinny mieć ten sam czas. Albo skompilowany i udostępniony, albo skompilowany i udostępniony.

Stóg
źródło
0

Po ustawieniu zakresu maven jako providedoznacza to, że po uruchomieniu wtyczki rzeczywista zastosowana wersja zależności będzie zależeć od zainstalowanej wersji Apache Maven.

Vishwa Ratna
źródło
0

Jeśli plik jar jest jak wykonywalny plik jar jar rozruchu wiosennego, wówczas zakres wszystkich zależności musi compileobejmować wszystkie pliki jar.

Ale jeśli plik jar używany w innych pakietach lub aplikacjach, nie musi uwzględniać wszystkich zależności w pliku jar, ponieważ te pakiety lub aplikacje mogą same zapewniać inne zależności.

Ali
źródło