Znalazłem wtyczkę maven-shadow-plugin w czyimś pliku pom.xml. Nigdy wcześniej nie korzystałem z wtyczki maven-shadow-plugin (i jestem Maven n00b), więc próbowałem zrozumieć powód używania tego i co on robi.
Spojrzałem na dokumenty Maven , jednak nie rozumiem tego stwierdzenia:
„Ta wtyczka umożliwia pakowanie artefaktu w słoik uber-jar, w tym jego zależności, oraz przyciemnianie - tj. Zmianę nazwy - pakietów niektórych zależności”.
Dokumentacja na stronie nie wydaje się zbyt przyjazna dla początkujących.
Co to jest „słoik uber”? Dlaczego ktoś miałby chcieć to zrobić? Po co zmieniać nazwy pakietów zależności? Próbowałem przejść przez przykłady na stronie apache plugin maven-shadow-plugin, takie jak „Wybieranie zawartości dla Uber Jar”, ale nadal nie rozumiem, co można osiągnąć dzięki „cieniowaniu”.
Docenione zostaną wszelkie wskazówki do przykładowych przykładów / przypadków użycia (z wyjaśnieniem, dlaczego w tym przypadku wymagane było cieniowanie - jaki problem rozwiązuje). Wreszcie, kiedy powinienem użyć wtyczki maven-shade-plug?
źródło
s/reallocation/relocation/
w powyższym komentarzu.Odpowiedzi:
Krótko mówiąc, Uber JAR to JAR zawierający wszystko.
Zwykle w Maven polegamy na zarządzaniu zależnościami. Artefakt zawiera same klasy / zasoby. Maven będzie odpowiedzialna za znalezienie wszystkich artefaktów (plików JAR itp.), Które są projektami w zależności od tego, kiedy projekt został zbudowany.
Uber-jar jest czymś, co bierze wszystkie zależności i wyodrębnia zawartość zależności i umieszcza je wraz z klasami / zasobami samego projektu w jednym dużym pliku JAR. Dzięki takiemu słoikowi jest łatwy do wykonania, ponieważ do uruchomienia aplikacji potrzebujesz tylko jednego dużego pliku JAR zamiast ton małych plików JAR. W niektórych przypadkach ułatwia to również dystrybucję.
Tylko uwaga. Unikaj używania Uber-Jar jako zależności Maven, ponieważ rujnuje to funkcję rozwiązywania zależności w Maven. Zwykle uber-jar tworzymy tylko dla końcowego artefaktu do faktycznego wdrożenia lub do ręcznej dystrybucji, ale nie do umieszczenia w repozytorium Maven.
Aktualizacja: Właśnie odkryłem, że nie odpowiedziałem na jedną część pytania: „Po co zmieniać nazwy pakietów zależności?”. Oto kilka krótkich aktualizacji i mam nadzieję, że pomogą ludziom, którzy mają podobne pytanie.
Stworzenie słoika Uber-jar dla łatwego wdrożenia to jeden przypadek użycia wtyczki zaciemniającej. Istnieją również inne typowe przypadki użycia, które wymagają zmiany nazwy pakietu.
Na przykład tworzę
Foo
bibliotekę, która zależy od konkretnej wersji (np. 1.0)Bar
biblioteki. Zakładając, że nie mogę korzystać z innej wersjiBar
lib (ponieważ zmiana API lub inne problemy techniczne itp.). Gdybym po prostu zadeklarowaćBar:1.0
jakoFoo
„s uzależnienia w Maven, można wpaść w Problem:Qux
Projekt jest w zależnościFoo
, a takżeBar:2.0
(i to nie można użyćBar:1.0
, ponieważQux
potrzeby używać nowej funkcjiBar:2.0
). Oto dylemat: czy należyQux
użyćBar:1.0
(któryQux
kod nie zadziała) lubBar:2.0
(któryFoo
kod nie zadziała)?Aby rozwiązać ten problem, programista
Foo
może zdecydować się na użycie wtyczki cieniowania, aby zmienić nazwę jego użyciaBar
, tak aby wszystkie klasy wBar:1.0
jar były osadzone wFoo
jar, a pakietBar
klas osadzonych został zmieniony zcom.bar
nacom.foo.bar
. Robiąc to,Qux
może bezpiecznie zależeć,Bar:2.0
ponieważ terazFoo
nie jest już zależnyBar
, i używa własnej kopii „zmienionej”Bar
znajdującej się w innym pakiecie.źródło
jar-with-dependency
deskryptora. W przypadku problemu uzaleŜnienia od uzaleŜnienia za pomocą słoika uber-jar już wspomniałem w mojej odpowiedzi: Nie używaj słoika uber-jar jako zależności, kropka. Trochę bardziej szczegółowo: przed utworzeniem słoika uber powinieneś mieć normalny projekt z normalną zależnością. Ten oryginalny artefakt jest tym, którego należy użyć jako zależności (zamiast uber-jar)Class.forName
działać?Zastanawiałem się ostatnio, dlaczego elasticsearch cienia i przenosi kilka (ale nie wszystkie) z jego zależności. Oto wyjaśnienie od opiekuna projektu, @kimchy :
- https://github.com/elasticsearch/elasticsearch/issues/2091#issuecomment-7156766
I kolejny tutaj od Drawr :
- https://github.com/elasticsearch/elasticsearch/pull/3244#issuecomment-20125452
To jest jeden przypadek użycia. Przykładem ilustrującym jest użycie wtyczki maven-shadow-plugin w pom.xml elasticsearch (v0.90.5). Te
artifactSet::include
linie instrukcji co co Zależności pociągnąć do słoika uber (w zasadzie, są one rozpakowane i i re-zapakowanego obok klas własnych elasticsearch kiedy słoik cel elasticsearch jest produkowany. (W przypadku, gdy nie wiedzą o tym już, plik JAR jest tylko plik ZIP, który zawiera klasy programu, zasoby itp. oraz niektóre metadane. Możesz go wyodrębnić, aby zobaczyć, jak jest złożony.)Te
relocations::relocation
linie są podobne, z tym że w każdym przypadku, ale także zastosować określone substytucje klas zależność jest - w tym przypadku, przynosząc je podorg.elasticsearch.common
.Wreszcie
filters
sekcja wyklucza niektóre elementy z docelowego pliku JAR, które nie powinny tam być - takie jak metadane JAR, pliki kompilacji mrówek, pliki tekstowe itp., Które są spakowane z pewnymi zależnościami, ale które nie należą do zwykłego pliku JAR.źródło
Małe ostrzeżenie
Chociaż to nie opisuje, dlaczego ktoś chciałby używać wtyczki maven-shadow-plugin (ponieważ wybrana odpowiedź dość dobrze to opisuje), chciałbym zauważyć, że miałem z tym problemy. Zmieniło JAR (od tego, co robi) i spowodowało regresję w moim oprogramowaniu.
Zamiast więc używać tej (lub wtyczki maven-jarjar), użyłem pliku binarnego JarJara, który wydaje się działać bez problemu.
Zamieszczam tutaj moje rozwiązanie, ponieważ znalezienie odpowiedniego rozwiązania zajęło mi trochę czasu.
Pobierz plik JAR JarJara
Możesz pobrać słoik tutaj: https://code.google.com/p/jarjar/ W menu po lewej stronie znajduje się link do pobrania.
Jak używać JarJar do przenoszenia klas JAR z jednego pakietu do drugiego
W tym przykładzie zmienimy pakiet z „com.fasterxml.jackson” na „io.kuku.dependencies.com.fasterxml.jackson”. - Źródłowy plik JAR nosi nazwę „jackson-databind-2.6.4.jar”, a nowy zmodyfikowany (docelowy) plik JAR nosi nazwę „kuku-jackson-databind-2.6.4.jar”. - Plik JAR „jarjar” znajduje się w wersji 1.4
Utwórz plik „rules.txt”. Zawartość pliku powinna być (uważaj na kropkę przed znakiem „@”): reguła com.fasterxml.jackson. ** io.kuku.dependencies.com.fasterxml.jackson. @ 1
Uruchom następującą komendę: java -jar jarjar-1.4.jar process rules.txt jackson-databind-2.6.4.jar kuku-jackson-databind-2.6.4.jar
Instalowanie zmodyfikowanych plików JAR w lokalnym repozytorium
W tym przypadku instaluję 3 pliki znajdujące się w folderze „c: \ my-jars \”.
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-annotations-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-adnotations -Dversion = 2.6.4 - Pakowanie = słoik
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-core-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-core -Dversion = 2.6.4 - Pakowanie = słoik
mvn install: install-file -Dfile = C: \ my-jars \ kuku-jackson-databind-2.6.4.jar -DgroupId = io.kuku.dependencies -DartifactId = kuku-jackson-adnotations -Dversion = 2.6.4 - Pakowanie = słoik
Używanie zmodyfikowanych plików JAR w pom pom projektu
W tym przykładzie jest to element „zależności” w projektach pom:
źródło
Myślę, że jednym z przykładów zapotrzebowania na „zacieniony” słoik jest funkcja Lambda AWS. Wydaje się, że pozwalają tylko na przesłanie 1 słoika, a nie całej kolekcji .jars, tak jak w typowym pliku .war. Zatem utworzenie jednego pliku .jar ze wszystkimi zależnościami projektu pozwala to zrobić.
źródło