Budowa słoika z tłuszczem za pomocą mavena

118

Mam bazę kodu, którą chcę rozpowszechniać jako jar. Ma również zależność od zewnętrznych słoików, które chcę umieścić w ostatnim słoiku.

Słyszałem, że można to zrobić za pomocą maven-assembly-plug-in, ale nie rozumiem, jak. Czy ktoś mógłby wskazać mi kilka przykładów.

W tej chwili używam słoika tłuszczu do pakowania ostatniego słoika. Chcę osiągnąć to samo używając Mavena.

bianca
źródło

Odpowiedzi:

143

Uwaga: jeśli korzystasz z aplikacji uruchamianej wiosną, przeczytaj koniec odpowiedzi

Dodaj następującą wtyczkę do swojej pom.xml najnowszej wersji można znaleźć pod adresem

...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>CHOOSE LATEST VERSION HERE</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>assemble-all</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
...

Po skonfigurowaniu tej wtyczki, uruchomienie mvn packageutworzy dwa pliki jar: jeden zawierający tylko klasy projektu, a drugi fat jar ze wszystkimi zależnościami z przyrostkiem „-jar-with-dependencies”.

jeśli chcesz poprawną classpathkonfigurację w czasie wykonywania, dodaj również następującą wtyczkę

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>fully.qualified.MainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Do aplikacji rozruchu sprężynowego użyj poniższej wtyczki (wybierz odpowiednią jej wersję)

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <fork>true</fork>
        <mainClass>${start-class}</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Jigar Joshi
źródło
1
Obecna wersja tej wtyczki to teraz 2.4
guerda
13
Jest to teraz przestarzałe i zamiast tego należy użyć wtyczki maven-shadow-plugin. Zobacz odpowiedź @phlogratos: stackoverflow.com/a/16222965/274350 .
Richard Neish,
2
Czy wtyczka Maven-Assembly-Plugin może zminimalizować rozmiar słoika na tłuszcz?
maja
1
@Richard Gdzie widzisz, że jest przestarzały? Nie mogłem tu nic znaleźć maven.apache.org/plugins/maven-assembly-plugin
user3833308
3
@ user3833308 „przestarzałe” może być niewłaściwym słowem, ale dokumentacja na maven.apache.org/plugins/maven-assembly-plugin mówi „Jeśli Twój projekt chce spakować artefakt w uber-jar, wtyczka asemblera zapewnia tylko podstawowe wsparcie. Aby uzyskać większą kontrolę, użyj wtyczki Maven Shade ”.
Richard Neish,
55

Możesz użyć wtyczki maven-shadow-plugin .

Po skonfigurowaniu wtyczki cieniowania w kompilacji polecenie mvn packageutworzy jeden pojedynczy plik jar ze wszystkimi zależnościami scalonymi z nim.

phlogratos
źródło
9
To jest teraz właściwy sposób, aby to zrobić. Dokumentacja maven-assembly-plugin mówi: "Jeśli twój projekt chce spakować twój artefakt w uber-jar, wtyczka assemblera zapewnia tylko podstawowe wsparcie. Aby uzyskać większą kontrolę, użyj wtyczki Maven Shade."
Richard Neish,
Ale jak mam pobrać ten pojedynczy plik .jar i użyć go do publikacji?
DanGordon,
42

Może chcesz maven-shade-pluginspakować zależności, zminimalizować nieużywany kod i ukryć zewnętrzne zależności, aby uniknąć konfliktów.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <minimizeJar>true</minimizeJar>
                        <createDependencyReducedPom>true</createDependencyReducedPom>
                        <dependencyReducedPomLocation>
                            ${java.io.tmpdir}/dependency-reduced-pom.xml
                        </dependencyReducedPomLocation>
                        <relocations>
                            <relocation>
                                <pattern>com.acme.coyote</pattern>
                                <shadedPattern>hidden.coyote</shadedPattern>
                            </relocation>
                        </relocations>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Bibliografia:

ggrandes
źródło
Jeśli ktoś się spotka Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found, po prostu usuń <minimizeJar>true</minimizeJar>.
koppor
Jeśli pojawi się wyjątek „java.lang.SecurityException: Invalid Signature file summary for Manifest main attributes”, to ten dodatek do powyższej sekcji konfiguracji pomoże: stackoverflow.com/a/6743609/38368
Danny Varod
12

właściwie, dodając

<archive>
   <manifest>
    <addClasspath>true</addClasspath>
    <packageName>com.some.pkg</packageName>                     
    <mainClass>com.MainClass</mainClass>
  </manifest>
</archive>

Deklaracja do maven-jar-plugin nie dodaje dla mnie głównego wpisu klasy do pliku manifestu. Musiałem dodać go do wtyczki maven-assembly-plugin, aby uzyskać to w manifeście

ameet chaubal
źródło
5

Do pakowania można użyć wtyczki onejar-maven-plugin . Zasadniczo gromadzi projekt i jego zależności w jednym pliku jar, obejmującym nie tylko plik jar projektu, ale także wszystkie zależności zewnętrzne jako „jar of jars”, np.

<build>
    <plugins>
        <plugin>
            <groupId>com.jolira</groupId>
            <artifactId>onejar-maven-plugin</artifactId>
                <version>1.4.4</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>one-jar</goal>
                        </goals>
                    </execution>
                </executions>
        </plugin>
    </plugins>
</build>

Uwaga 1: Opcje konfiguracji są dostępne na stronie głównej projektu .

Uwaga 2: Z jednego lub drugiego powodu projekt onejar-maven-plugin nie został opublikowany w Maven Central. Jednak jolira.com śledzi oryginalny projekt i publikuje go pod adresem groupId com.jolira.

matsev
źródło
Czy można wybrać zależności, z którymi chcesz się spakować? Na przykład, jeśli a.jar i b.jar są zewnętrznymi plikami jar i chcę zapakować tylko a.jar do ostatecznego jar, czy jest to możliwe / konfigurowalne?
bianca
Widzę również, że rzeczy z jednego słoika zostały zapakowane w ostatnim słoiku. To znacznie zwiększyło rozmiar końcowego słoika. Czy można wybrać zewnętrzne słoiki, które zamierzasz umieścić w finalnym słoiku? Oto logi z jednego słoika: pastebin.com/UwniQJ2X
bianca
Nie wiem, czy możesz skonfigurować, co jest dołączone, czy nie. Zasadniczo plik one-jar zawiera wszystkie zależności, które są określone w Twoim projekcie, w tym zależności przechodnie, więc tak, ostateczny plik jar prawdopodobnie stanie się duży, jeśli masz wiele zależności. Niektóre narzuty zostaną dodane przez one-jar, aby Java działała ze strukturą „jar of jars”.
matsev
2

Alternatywą jest użycie maven odcień wtyczki zbudować uber-jar.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version> Your Version Here </version>
    <configuration>
            <!-- put your configurations here -->
    </configuration>
    <executions>
            <execution>
                    <phase>package</phase>
                    <goals>
                            <goal>shade</goal>
                    </goals>
            </execution>
    </executions>
</plugin>
Stanislav
źródło