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?

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

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.


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,


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


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.)


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.


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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.