Chcę spakować mój projekt do jednego pliku wykonywalnego JAR w celu dystrybucji.
Jak mogę utworzyć pakiet projektu Maven ze wszystkimi plikami JAR zależności w moim wyjściowym pliku JAR?
Chcę spakować mój projekt do jednego pliku wykonywalnego JAR w celu dystrybucji.
Jak mogę utworzyć pakiet projektu Maven ze wszystkimi plikami JAR zależności w moim wyjściowym pliku JAR?
Odpowiedzi:
i uruchamiasz to z
Cel kompilacji powinien zostać dodany przed złożeniem: pojedynczy lub inny kod własnego projektu nie jest uwzględniony.
Zobacz więcej szczegółów w komentarzach.
Zwykle ten cel jest powiązany z fazą kompilacji, aby wykonać się automatycznie. Zapewnia to zbudowanie
mvn install
pliku JAR podczas wykonywania lub wykonywania wdrożenia / wydania.źródło
mvn clean compile assembly:single
.<appendAssemblyId>false</appendAssemblyId>
do,configuration
aby uniknąć irytującego przyrostka „compile
i jesteś pieprzony.Wtyczki zależności można użyć do wygenerowania wszystkich zależności w osobnym katalogu przed fazą pakietu, a następnie włączenia jej do ścieżki klas manifestu:
Alternatywnie użyj
${project.build.directory}/classes/lib
jako OutputDirectory do zintegrowania wszystkich plików jar w głównym jar, ale wtedy będziesz musiał dodać niestandardowy kod ładowania klas, aby załadować jar.źródło
${project.build.directory}/classes/lib
jakooutputDirectory
głównego pliku .jar ze wszystkimi zależnościami, ale - jak dodać niestandardowy kod ładujący klasy, aby załadować te słoiki? Muszę zrobić wykonywania prac takich jak:java -jar main-jar-with-deps.jar
. Czy to możliwe ?Blogowałem o różnych sposobach na zrobienie tego.
Zobacz słój wykonywalny z Apache Maven (WordPress)
lub executable-jar-with-maven-example (GitHub)
Notatki
Te zalety i wady zapewnia Stephan .
Do ręcznego wdrażania
Skopiuj zależności do określonego katalogu
Spraw, aby jar był wykonywalny, a Classpath świadomy
W tym momencie
jar
jest to możliwe do wykonania z zewnętrznymi elementami ścieżki klasy.Twórz archiwa do wdrożenia
jar
Plik jest wykonywalny tylko z rodzeństwem...lib/
katalogu. Musimy stworzyć archiwa do wdrożenia z katalogiem i jego zawartością.Teraz masz,
target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
który zawierajar
ilib/*
.Wtyczka Apache Maven Assembly
Masz
target/${project.bulid.finalName}-jar-with-dependencies.jar
.Wtyczka Apache Maven Shade
Masz
target/${project.build.finalName}-shaded.jar
.wtyczka onejar-maven
Wtyczka Spring Boot Maven
Masz
target/${project.bulid.finalName}-spring-boot.jar
.źródło
Biorąc odpowiedź bez odpowiedzi i ponownie ją formatując, mamy:
Następnie zaleciłbym uczynienie z tego naturalnej części twojej kompilacji, a nie czegoś, co można nazwać jawnie. Aby uczynić to integralną częścią twojej kompilacji, dodaj tę wtyczkę do swojej
pom.xml
i powiąż ją zepackage
zdarzeniem cyklu życia. Jednak gotcha polega na tym, że musisz wywołaćassembly:single
cel, jeśli umieścisz to w pliku pom.xml, a nazwałbyś „assembly: assembly”, jeśli wykonasz to ręcznie z wiersza poleceń.źródło
Użyj wtyczki maven-shadow-plug, aby spakować wszystkie zależności w jednym słoiku. Można go również użyć do zbudowania pliku wykonywalnego, określając klasę główną. Po próbie użycia maven-assembly i maven-jar odkryłem, że ta wtyczka najlepiej odpowiada moim potrzebom.
Uważam tę wtyczkę za szczególnie przydatną, ponieważ łączy ona zawartość określonych plików zamiast nadpisywać je. Jest to potrzebne, gdy istnieją pliki zasobów o tej samej nazwie w słoikach, a wtyczka próbuje spakować wszystkie pliki zasobów
Zobacz przykład poniżej
źródło
Dawno używałem wtyczki maven , ale nie mogłem znaleźć rozwiązania problemu
"already added, skipping"
. Teraz używam innej wtyczki - onejar-maven-plugin . Przykład poniżej (mvn package
build jar):Musisz dodać repozytorium dla tej wtyczki:
źródło
Możesz użyć wtyczki maven-dependence, ale pytanie brzmiało, jak utworzyć wykonywalny plik JAR. Aby to zrobić, wymagana jest następująca modyfikacja odpowiedzi Matthew Franglena (przy okazji, użycie wtyczki zależności trwa dłużej, gdy zaczyna się od czystego celu):
źródło
Możesz użyć wtyczki maven-shadow, aby zbudować słoik Uber, jak poniżej
źródło
Inną opcją, jeśli naprawdę chcesz przepakować inne pliki JAR w jednym wynikowym pliku JAR, jest wtyczka Maven Assembly . Rozpakowuje, a następnie przepakowuje wszystko do katalogu przez
<unpack>true</unpack>
. Wtedy miałbyś drugie przejście, które wbudowało go w jeden ogromny JAR.Inną opcją jest wtyczka OneJar . Wykonuje powyższe czynności przepakowywania w jednym kroku.
źródło
Do pliku pom.xml możesz dodać następujące elementy :
Następnie musisz przejść przez konsolę do katalogu, w którym znajduje się plik pom.xml. Następnie musisz wykonać montaż mvn: pojedynczy, a następnie plik wykonywalny JAR z zależnościami zostanie skompilowany. Możesz to sprawdzić, przechodząc do katalogu wyjściowego (docelowego) za pomocą cd ./target i uruchamiając jar za pomocą polecenia podobnego do java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar .
Testowałem to z Apache Maven 3.0.3 .
źródło
Przeanalizowałem każdą z tych odpowiedzi, szukając tłustego pliku wykonywalnego zawierającego wszystkie zależności i żadna z nich nie działała poprawnie. Odpowiedzią jest wtyczka cieniująca, która jest bardzo łatwa i bezpośrednia.
Pamiętaj, że aby zależności działały poprawnie, musisz mieć zakres kompilacji lub środowiska wykonawczego.
Ten przykład pochodzi z mkyong.com
źródło
plugin
Elementem idzie wpom.xml
niedostateczniebuild/plugins
.Możesz połączyć
maven-shade-plugin
imaven-jar-plugin
.maven-shade-plugin
Pakuje swoje zajęcia i wszystkie zależności w jednym pliku jar.maven-jar-plugin
aby określał główną klasę pliku wykonywalnego jar (zobacz Konfigurowanie ścieżki klasy , rozdział „Tworzenie pliku jar ”).Przykładowa konfiguracja POM dla
maven-jar-plugin
:Na koniec utwórz plik wykonywalny jar, wywołując:
źródło
Moim zdaniem Ken Liu ma rację. Wtyczka zależności maven pozwala rozszerzyć wszystkie zależności, które można następnie traktować jako zasoby. Pozwala to na włączenie ich do głównego artefaktu. Użycie wtyczki asemblera tworzy wtórny artefakt, który może być trudny do modyfikacji - w moim przypadku chciałem dodać niestandardowe wpisy manifestu. Mój pom skończył jako:
źródło
Tak powinno być:
Rozpakowanie musi odbywać się w fazie generowania zasobów, ponieważ w fazie pakietowej nie będzie uwzględniane jako zasoby. Wypróbuj czysty pakiet, a zobaczysz.
źródło
Masz problem ze zlokalizowaniem udostępnionego pliku zestawu za pomocą maven-assembly-plugin-2.2.1?
Spróbuj użyć parametru konfiguracyjnego descriptorId zamiast parametrów descriptors / descriptor lub descriptorRefs / descriptorRef.
Żadne z nich nie robi tego, czego potrzebujesz: poszukaj pliku na ścieżce klasy. Oczywiście musisz dodać pakiet, w którym znajduje się współużytkowany zestaw, na ścieżce klasy wtyczki maven-assembly-plugin (patrz poniżej). Jeśli używasz Maven 2.x (nie Maven 3.x), może być konieczne dodanie tej zależności w najwyższym nadrzędnym pliku pom.xml w sekcji pluginManagement.
Widzieć to po więcej szczegółów.
Klasa: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader
Przykład:
źródło
Aby rozwiązać ten problem, użyjemy wtyczki Maven Assembly Plug, która utworzy plik JAR wraz z jego plikami JAR zależności w jednym pliku wykonywalnym JAR. Wystarczy dodać poniżej konfiguracji wtyczki do pliku pom.xml.
Po wykonaniu tej czynności nie zapomnij uruchomić narzędzia MAVEN za pomocą tego polecenia mvn clean compile assembly: single
http://jkoder.com/maven-creating-a-jar-together-with-its-dependency-jars-into-a-single-executable-jar-file/
źródło
Nie odpowiem bezpośrednio na pytanie, ponieważ inni już to zrobili, ale naprawdę zastanawiam się, czy dobrym pomysłem jest osadzenie wszystkich zależności w słoju projektu.
Widzę sens (łatwość wdrożenia / użycia), ale zależy to od przypadku użycia twojego obiektu (i mogą istnieć alternatywy (patrz poniżej)).
Jeśli używasz go w pełni autonomicznie, dlaczego nie.
Ale jeśli używasz swojego projektu w innych kontekstach (np. W aplikacji internetowej lub upuszczono w folderze, w którym znajdują się inne słoiki), możesz mieć duplikaty słoików w ścieżce klasy (te w folderze, te w słoikach). Może nie jest to oferta licytacyjna, ale zwykle tego unikam.
Dobra alternatywa:
W ten sposób, z końcem tylko manifestem i „specjalnym głównym dynamicznym modułem ładującym klasy”, możesz rozpocząć swój projekt:
źródło
Aby utworzyć wykonywalny plik JAR z poziomu wiersza poleceń, wystarczy uruchomić poniższe polecenie ze ścieżki projektu:
źródło
pom.xml
przeciwnym razieError reading assemblies: No assembly descriptors found.
. I tak mi się zdarza.To najlepszy sposób, jaki znalazłem:
Przy tej konfiguracji wszystkie zależności będą znajdować się w
/dependency-jars
. Moja aplikacja nie maMain
klasy, tylko kontekstowe, ale jedna z moich zależności maMain
klasę (com.myDomain.etc.MainClassName
), która uruchamia serwer JMX i odbiera parametrstart
lubstop
parametr. Dzięki temu mogłem uruchomić moją aplikację w następujący sposób:Czekam, że przyda się wam wszystkim.
źródło
Porównałem wtyczki drzewa wspomniane w tym poście. Wygenerowałem 2 słoiki i katalog ze wszystkimi słojami. Porównałem wyniki i zdecydowanie wtyczka maven-shadow-plug jest najlepsza. Wyzwanie polegało na tym, że mam wiele zasobów wiosennych, które musiały zostać połączone, a także jax-rs i usługi JDBC. Wszystkie zostały poprawnie połączone przez wtyczkę cienia w porównaniu z wtyczką maven-assembly-plug. W takim przypadku wiosna nie powiedzie się, chyba że skopiujesz je do własnego folderu zasobów i scalisz je ręcznie jeden raz. Obie wtyczki generują prawidłowe drzewo zależności. Miałem wiele zakresów, takich jak test, dostarczanie, kompilacja itp. Test i dostarczone zostały pominięte przez obie wtyczki. Obaj wyprodukowali ten sam manifest, ale udało mi się skonsolidować licencje z wtyczką cieniowania za pomocą ich transformatora. Z wtyczką zależną od maven oczywiście nie mam te problemy, ponieważ słoiki nie są wyodrębniane. Ale jak niektórzy inni wskazali, musisz mieć jeden dodatkowy plik (i), aby działać poprawnie. Oto wycinek pliku pom.xml
źródło
Coś, co zadziałało dla mnie to:
Miałem wyjątkowy przypadek, ponieważ moja zależność dotyczyła systemu pierwszego:
Zmieniłem kod dostarczony przez @ user189057 ze zmianami: 1) Wtyczka zależności od maven jest wykonywana w fazie „przygotuj pakiet” 2) Wyciągam rozpakowane klasy bezpośrednio do „docelowych / klas”
źródło
Spróbowałem tutaj najbardziej głosowanej odpowiedzi i udało mi się uruchomić słoik. Ale program nie działał poprawnie. Nie wiem jaki był tego powód. Kiedy próbuję uciec
Eclipse
, otrzymuję inny wynik, ale kiedy uruchamiam jar z wiersza poleceń, otrzymuję inny wynik (ulega awarii z powodu błędu specyficznego dla programu).Miałem podobny wymóg jak PO, tylko że miałem zbyt wiele zależności (Maven) dla mojego projektu. Na szczęście jedynym rozwiązaniem, które działało dla mnie, było takie użycie
Eclipse
. Bardzo proste i bardzo proste. To nie jest rozwiązanie OP, ale rozwiązanie dla kogoś, kto ma podobne wymagania, ale ma wiele zależności Maven,1) Kliknij prawym przyciskiem myszy folder projektu (w Eclipse) i wybierz
Export
2) Następnie wybierz
Java
->Runnable Jar
3) Zostaniesz poproszony o wybranie lokalizacji pliku jar
4) Na koniec wybierz klasę, która ma metodę Main, którą chcesz uruchomić, a następnie wybierz
Package dependencies with the Jar file
i kliknijFinish
źródło
Może to być również opcja. Będziesz mógł zbudować plik jar
źródło
Dla każdego, kto szuka opcji wykluczenia określonych zależności z Uber-jar, jest to rozwiązanie, które działało dla mnie:
Nie jest to więc konfiguracja wtyczki mvn-assembly-plugin, ale właściwość zależności.
źródło
Istnieją już miliony odpowiedzi, chciałem dodać, że nie potrzebujesz,
<mainClass>
jeśli nie musisz dodawać entryPoint do swojej aplikacji. Na przykład interfejsy API niekoniecznie muszą miećmain
metodę.Konfiguracja wtyczki maven
budować
zweryfikować
źródło
Dodaj do pom.xml:
i
Otóż to. Następny pakiet mvn utworzy dodatkowo jeden słoik tłuszczu, w tym wszystkie słoiki zależności.
źródło
Wtyczka maven-assembly-plug działała dla mnie świetnie. Spędziłem godziny z wtyczką zależności od raju i nie mogłem sprawić, by działała. Głównym powodem było to, że musiałem wyraźnie zdefiniować w sekcji konfiguracji elementy artefaktu, które powinny zostać uwzględnione zgodnie z opisem w dokumentacji . Jest tam przykład przypadków, w których chcesz go użyć, takich jak:,
mvn dependency:copy
gdzie nie ma żadnych artefaktów, ale to nie działa.źródło
Ten post na blogu pokazuje inne podejście do łączenia wtyczek maven-jar i maven-assembly. Za pomocą xml konfiguracji zestawu z posta na blogu można również kontrolować, czy zależności będą rozszerzane, czy tylko gromadzone w folderze i wskazywane przez wpis ścieżki klasy w manifeście:
I dokładnie ten jest opisany tutaj: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/
źródło
źródło
Okej, więc to jest moje rozwiązanie. Wiem, że nie używa pliku pom.xml. Miałem jednak problem z tym, że mój program kompilował się i działał na Netbeans, ale nie działał, kiedy próbowałem Java -jar MyJarFile.jar. Teraz nie do końca rozumiem Maven i myślę, że dlatego miałem problem z włączeniem mojego pliku jar do biblioteki Netbeans 8.0.2 w celu umieszczenia go w pliku jar. Myślałem o tym, jak używałem plików jar bez Maven w środowisku Eclipse.
To Maven może kompilować wszystkie zależności i wtyczki. Nie Netbeans. (Jeśli możesz uzyskać Netbeans i móc użyć do tego java .jar, proszę powiedz mi jak (^. ^) V)
[Rozwiązane - dla systemu Linux] poprzez otwarcie terminala.
Następnie
Kolejny
Kolejny
Spowoduje to utworzenie pliku jar w katalogu docelowym.
Teraz
(Może być konieczne uruchomienie:
chmod +x MyJarFile-1.0-jar-with-dependencies.jar
)I w końcu
Proszę zobaczyć
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException
Zamieszczę to rozwiązanie na kilku innych stronach z podobnym problemem. Mam nadzieję, że uda mi się uratować kogoś przed tygodniem frustracji.
źródło